Flutter迴圈滑動的PageView
序言
Android原生裡一般會使用ViewPager來實現Banner區域,當然Flutter中的PageView也可以實現類似的效果,今天就來擼一把迴圈滑動的PageView。
在Android中想要實現迴圈滑動的ViewPager,最常用的方法是,在原資料來源的基礎上,通過前後補位來操作:即準備新的資料集合list , 第一個位置插入原資料中的最後一個元素、最後一個位置插入原資料中的第一個元素,Flutter中PageView實現迴圈滑動的方法如出一轍,如下圖所示:
在使用者滑動過程中,當(2)被選中後,無動畫切換到2的位置;當(0)被選中後,此時無動畫切換到0的位置。即可實現迴圈滑動的PageView。
準備新的資料來源
這裡需要解釋下,如果只有一個資料的話,不考慮迴圈滑動
///初始化Page
///
///準備一個新的資料來源list
///在原資料data的基礎上,前後各新增一個view data[data.length-1]、data[0]
void _initWidget() {
currentIndex = widget.controller.initialPage;
if (widget.children == null || widget.children.isEmpty) return;
if (widget.children.length == 1) {
_children.addAll(widget.children);
} else {
_children.add(widget.children[widget.children.length - 1]);
_children.addAll(widget.children);
_children.add(widget.children[0]);
}
}
當使用者在滑動到新位置的Page後,會觸發PageView的回撥監聽onPageChanged(int index),引數即為新選中的Page索引,此時我們需要及時將頁面切換到正確的位置
///Page切換後的回撥,及時修復索引
_onPageChanged(int index) async {
if (index == 0) {
//當前選中的是第一個位置,自動選中倒數第二個位置
currentIndex = _children.length - 2;
await Future.delayed(Duration(milliseconds: 400));
widget.controller?.get()?.jumpToPage(currentIndex);
realPosition = currentIndex - 1;
} else if (index == _children.length - 1) {
//當前選中的是倒數第一個位置,自動選中第二個索引
currentIndex = 1;
await Future.delayed(Duration(milliseconds: 400));
widget.controller?.get()?.jumpToPage(currentIndex);
realPosition = 0;
} else {
currentIndex = index;
realPosition = index - 1;
if (realPosition < 0) realPosition = 0;
}
setState(() {});
}
你可能會發現在呼叫jumpToPage之前為什麼延遲了400毫秒,這裡做一個短暫的延遲是因為PageView在切換頁面後如果立即jumpToPage會出現卡頓的現象,做短暫延遲可以規避這個問題。
定時切換
目前已經實現了PageView的迴圈滑動,那麼現在我們加一個定時器,每隔2s自動切換下一個頁面。
///建立定時器
void createTimer() {
if (widget.isTimer) {
cancelTimer();
_timer = Timer.periodic(widget.delay, (timer) => _scrollPage());
}
}
///定時切換PageView的頁面
void _scrollPage() {
++currentIndex;
var next = currentIndex % _children?.length;
widget.controller?.get()?.animateToPage(
next,
duration: widget.duration,
curve: Curves.ease,
);
}
滑動衝突
到這裡就實現了可以定時自動迴圈滑動的PageView,但是看下實際效果你會發現,當使用者在滑動過程中,定時器還在進行,此時就需要取消定時器,當使用者手指離開後再開啟定時器自動輪播。
所以這裡你可以給PageView包裹一層NotificationListener來監聽使用者滑動
@override
Widget build(BuildContext context) => NotificationListener(
onNotification: (notification) => _onNotification(notification),
child: PageView(
scrollDirection: widget.scrollDirection,
reverse: widget.reverse,
controller: widget.controller?.get(),
physics: widget.physics,
pageSnapping: widget.pageSnapping,
onPageChanged: (index) => _onPageChanged(index),
children: _children,
dragStartBehavior: widget.dragStartBehavior,
allowImplicitScrolling: widget.allowImplicitScrolling,
restorationId: widget.restorationId,
clipBehavior: widget.clipBehavior,
),
);
///Page滑動監聽
_onNotification(notification) {
if (notification is ScrollStartNotification) {
isEnd = false;
} else if (notification is UserScrollNotification) {
//使用者滑動時回撥順序:start - user , end - user
if (isEnd) {
isUserGesture = false;
_start();
return;
}
isUserGesture = true;
_stop();
} else if (notification is ScrollEndNotification) {
isEnd = true;
if (isUserGesture) {
_start();
}
}
}
值得注意的是,自動滑動和使用者滑動都會觸發start、end事件,但是使用者滑動時會觸發user事件,滑動時回撥順序:start - user 、 end - user,所以只需要在user事件回撥中判斷是否手指離開了,即可區分使用者滑動和頁面滑動,實現使用者滑動狀態下暫停定時器,使用者手指離開後啟動定時器。
看下最終的實現效果,程式碼裡時加了頁面圓點指示器的,可以參考程式碼自定義配置。
相關文章
- 左右迴圈滑動的viewpagerViewpager
- [Flutter]從零開始實現一個巢狀滑動的PageView(三)Flutter巢狀View
- [Flutter]從零開始實現一個巢狀滑動的PageView(一)Flutter巢狀View
- android可以無限迴圈滑動的ViewPagerAndroidViewpager
- ViewPager實現左右無限迴圈滑動Viewpager
- Flutter for迴圈案例Flutter
- 16、Flutter Widget - PageView;FlutterView
- 直播系統app原始碼,垂直,水平無限迴圈滑動APP原始碼
- Flutter 滑動體系Flutter
- JavaScript的map迴圈、forEach迴圈、filter迴圈、reduce迴圈、reduceRight迴圈JavaScriptFilter
- flutter 中監聽滑動事件Flutter事件
- HarmonyOS 與 ArkTS | ForEach 迴圈渲染 + List 實現滑動影片列表
- Flutter Flame 教程2 -- Game Loop遊戲迴圈FlutterGAMOOP遊戲
- Flutter之可滑動WidgetFlutter
- 無縫迴圈滾動
- C語言——迴圈結構(for迴圈,while迴圈,do-while迴圈)C語言While
- flutter: 執行緒通訊與訊息迴圈Flutter執行緒
- 無限for迴圈(死迴圈)
- Unity-卡片迴圈滾動Unity
- 文字垂直迴圈滾動效果
- javascript無限迴圈滾動JavaScript
- Flutter: BottomNavigationBar + PageView 翻頁時崩潰FlutterNavigationView
- 迴圈中的非同步&&迴圈中的閉包非同步
- for迴圈的理解
- while迴圈以及do while迴圈While
- 微互動(五)——微互動的迴圈與模式模式
- C#程式設計基礎第七課:C#中的基本迴圈語句:while迴圈、do-while迴圈、for迴圈、foreach迴圈的使用C#程式設計While
- 聊聊Flutter中的常見滑動手勢衝突Flutter
- Java入門學習-學習if & else,for迴圈,foreach迴圈,while迴圈的用法。JavaWhile
- 迴圈
- if迴圈
- flutter原始碼系列 PageView原始碼分析以及監聽事件Flutter原始碼View事件
- 探討兩種迴圈表示方法的區別,while迴圈與for迴圈的小總結While
- 分支、迴圈語句動態展示
- 04流程控制 for迴圈,while迴圈While
- PLSQL Language Referenc-PL/SQL控制語句-迴圈語句-FOR迴圈-FOR迴圈中的索引SQL索引
- [譯] Flutter 非同步程式設計:Future、Isolate 和事件迴圈Flutter非同步程式設計事件
- 【基礎題】【for迴圈】二重迴圈