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事件回撥中判斷是否手指離開了,即可區分使用者滑動和頁面滑動,實現使用者滑動狀態下暫停定時器,使用者手指離開後啟動定時器。
看下最終的實現效果,程式碼裡時加了頁面圓點指示器的,可以參考程式碼自定義配置。
相關文章
- [Flutter]從零開始實現一個巢狀滑動的PageView(一)Flutter巢狀View
- [Flutter]從零開始實現一個巢狀滑動的PageView(三)Flutter巢狀View
- android可以無限迴圈滑動的ViewPagerAndroidViewpager
- Flutter for迴圈案例Flutter
- 16、Flutter Widget - PageView;FlutterView
- HarmonyOS 與 ArkTS | ForEach 迴圈渲染 + List 實現滑動影片列表
- 直播系統app原始碼,垂直,水平無限迴圈滑動APP原始碼
- Flutter 滑動體系Flutter
- Flutter之可滑動WidgetFlutter
- Flutter: BottomNavigationBar + PageView 翻頁時崩潰FlutterNavigationView
- flutter 中監聽滑動事件Flutter事件
- Flutter Flame 教程2 -- Game Loop遊戲迴圈FlutterGAMOOP遊戲
- Flutter基礎(七)Scrolling Widget之ListView、GridView、PageViewFlutterView
- Flutter 基礎(七)Scrolling Widget 之 ListView、GridView、PageViewFlutterView
- for 迴圈與 while 迴圈While
- while迴圈 case迴圈While
- C語言——迴圈結構(for迴圈,while迴圈,do-while迴圈)C語言While
- 無限for迴圈(死迴圈)
- flutter: 執行緒通訊與訊息迴圈Flutter執行緒
- 迴圈中的非同步&&迴圈中的閉包非同步
- Unity-卡片迴圈滾動Unity
- for迴圈的概念
- for迴圈的理解
- C#程式設計基礎第七課:C#中的基本迴圈語句:while迴圈、do-while迴圈、for迴圈、foreach迴圈的使用C#程式設計While
- 聊聊Flutter中的常見滑動手勢衝突Flutter
- while迴圈以及do while迴圈While
- 探討兩種迴圈表示方法的區別,while迴圈與for迴圈的小總結While
- flutter原始碼系列 PageView原始碼分析以及監聽事件Flutter原始碼View事件
- if for迴圈
- For 迴圈
- if迴圈
- 迴圈
- for迴圈
- 分支、迴圈語句動態展示
- PTA 7-1 迴圈移動
- Flutter列表滑動曝光埋點,支援SliverList、SliverGridFlutter
- 04流程控制 for迴圈,while迴圈While
- kotlin的迴圈使用Kotlin