Flutter列表滾動定位超強(qiáng)輔助庫使用示例詳解
一、痛點(diǎn)
痛點(diǎn)一:Flutter 官方提供了 ScrollController,調(diào)用下方兩個方法可以滾動到指定偏移處
void jumpTo(double value)
Future<void> animateTo(
double offset, {
required Duration duration,
required Curve curve,
})
但是官方?jīng)]有提供滾動到指定下標(biāo)位置的功能
痛點(diǎn)二:
為了解決痛點(diǎn)一,業(yè)內(nèi)有很多第三方庫實(shí)現(xiàn)了這個功能,其中最知名的莫過于谷歌的 scrollable_positioned_list
而這些庫都有一些相同的問題:
- 侵入性強(qiáng),必須使用他們提供的
Widget來構(gòu)建列表視圖 - 不支持
GridView
對此,我決定自己編寫一個庫(flutter_scrollview_observer)來實(shí)現(xiàn)這個功能,以及解決以上的問題。
二、優(yōu)點(diǎn)
- 侵入性低,不會限制你的列表視圖實(shí)現(xiàn),只要求將列表視圖做為
ViewObserver的child,如果不想用了,直接移除掉ViewObserver即可。 - 基于【不會限制你的列表視圖實(shí)現(xiàn)】這一點(diǎn),
flutter_scrollview_observer支持所有的列表Widget,如:ListView、GridView,甚至CustomSrollView - 防抖動,如果在滾動到指定下標(biāo)時,列表尾部的可滾動區(qū)域已不足以支撐滾動到相應(yīng)位置,則會自動滾動到最底部,避免回彈的問題
下面正式介紹一下這個庫的使用
三、使用
1、ListView
正常創(chuàng)建和使用 ScrollController 實(shí)例
這里你可以使用 ListView 或者 CustomSrollView 的 SliverList
ScrollController scrollController = ScrollController();
ListView _buildListView() {
return ListView.separated(
controller: scrollController,
...
);
}
創(chuàng)建 ListObserverController 實(shí)例并將其傳遞給 ListViewObserver
ListObserverController observerController = ListObserverController(controller: scrollController); ListViewObserver( controller: observerController, child: _buildListView(), ... )
注意:創(chuàng)建 ListObserverController 實(shí)例時需要傳入列表的 ScrollController 實(shí)例。 這一步很重要,因?yàn)?flutter_scrollview_observer 內(nèi)部實(shí)現(xiàn)原理是基于官方 ScrollController 提供的 jumpTo 和 animateTo 方法
現(xiàn)在即可滾動到指定下標(biāo)位置了
// 無動畫滾動至下標(biāo)位置 observerController.jumpTo(index: 100) // 動畫滾動至下標(biāo)位置 observerController.animateTo( index: 100, duration: const Duration(seconds: 1), curve: Curves.ease, );

2、GridView
內(nèi)容與 ListView 基本一致


正常創(chuàng)建和使用 ScrollController 實(shí)例
Widget _buildGridView() {
return GridView.builder(
...
controller: scrollController,
...
);
}
創(chuàng)建 GridObserverController 實(shí)例并將其傳遞給 GridViewObserver
GridObserverController observerController = GridObserverController(controller: scrollController); GridViewObserver( controller: observerController, child: _buildGridView(), )
現(xiàn)在即可滾動到指定下標(biāo)位置了
observerController.jumpTo( index: 40, ); observerController.animateTo( index: 40, duration: const Duration(seconds: 1), curve: Curves.ease, );
3、CustomSrollView
支持 SliverList 和 SliverGrid 混合使用的情況!

如上圖所示,CustomSrollView 的 slivers 中包含有 SliverList 和 SliverGrid
- 點(diǎn)擊右下角第一個按鈕可滾動到
SliverList的第29行 - 點(diǎn)擊第二個按鈕可滾動到
SliverGrid的第10的子部件所在行
正常創(chuàng)建和使用 ScrollController 實(shí)例
Widget _buildScrollView() {
return CustomScrollView(
controller: scrollController,
// scrollDirection: Axis.horizontal,
slivers: [
_buildSliverListView(),
_buildSliverGridView(),
],
);
}
正常創(chuàng)建你的 SliverList 和 SliverGrid,并將它們的 BuildContext 記錄起來
Widget _buildSliverListView() {
return SliverList(
delegate: SliverChildBuilderDelegate(
(ctx, index) {
_sliverListCtx ??= ctx;
...
},
...
),
);
}
Widget _buildSliverGridView() {
return SliverGrid(
...
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
_sliverGridCtx ??= context;
...
},
...
),
);
}
創(chuàng)建 SliverObserverController 實(shí)例并將其傳遞給 SliverViewObserver
注意:在 sliverListContexts 里返回剛才記錄的兩個 Sliver 的 BuildContext
SliverObserverController observerController = SliverObserverController(controller: scrollController);
SliverViewObserver(
controller: observerController,
child: _buildScrollView(),
sliverListContexts: () {
return [
if (_sliverListCtx != null) _sliverListCtx!,
if (_sliverGridCtx != null) _sliverGridCtx!,
];
},
...
),
現(xiàn)在即可滾動到指定下標(biāo)位置了
observerController.animateTo( sliverContext: _sliverListCtx, index: 29, duration: const Duration(milliseconds: 300), curve: Curves.easeInOut, ); observerController.animateTo( sliverContext: _sliverGridCtx, index: 10, duration: const Duration(milliseconds: 300), curve: Curves.easeInOut, );
四、說明
1、ViewObserver 的選擇
建議使用相應(yīng)的 ViewObserver:
- 如果是
ListView或者純SliverList,建議使用ListViewObserver - 如果是
GridView或者純SliverGrid,建議使用GridViewObserver - 如果是
SliverList和SliverGrid,則使用SliverViewObserver
這樣在 onObserve 回調(diào)中拿到數(shù)據(jù)模型后不用再對其進(jìn)行類型判斷與轉(zhuǎn)換。
2、isFixedHeight
子部件為固定高度的情況下,請?jiān)O(shè)置 isFixedHeight 為 true,以提升性能!
observerController.jumpTo( index: 100, isFixedHeight: true ); observerController.animateTo( index: 100, isFixedHeight: true, duration: const Duration(seconds: 1), curve: Curves.ease, );
3、sliverContext 是否需要傳
jumpTo({
required int index,
BuildContext? sliverContext,
bool isFixedHeight = false,
})
animateTo({
required int index,
required Duration duration,
required Curve curve,
BuildContext? sliverContext,
bool isFixedHeight = false,
})
如上,jumpTo 和 animateTo 方法中都有一個 sliverContext 參數(shù),這是用來指定哪個 sliver 進(jìn)行滾動操作的。
如果不傳 sliverContext,則默認(rèn)會是列表中的第一個 sliver,只有你想讓非第一個 sliver 進(jìn)行滾動的時候才需要傳該值
五、可現(xiàn)實(shí)的功能
1、獲得當(dāng)前視窗中的子部件信息

如上圖控制臺所示,在滾動的過程中可以實(shí)時獲取正在顯示的子部件的數(shù)據(jù)。
2、視頻列表自動播放

這種功能很常見,在列表滾動的時候,指定區(qū)域內(nèi)的被命中的視頻便會自動進(jìn)行播放。
3、模塊定位

一般詳情頁中都會有的功能,在列表視圖滾動的時候,頂部定位導(dǎo)航視圖跟著更新下標(biāo),點(diǎn)擊導(dǎo)航視圖某個下標(biāo)則會定位到對應(yīng)的模塊
六、最后
如果這個庫對你很有幫助,請不吝給個 star 吧
GitHub: flutter_scrollview_observer
以上就是Flutter列表滾動定位超強(qiáng)輔助庫使用示例詳解的詳細(xì)內(nèi)容,更多關(guān)于Flutter列表滾動定位輔助庫的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
IOS開發(fā)OC代碼中創(chuàng)建Swift編寫的視圖控制器
這篇文章主要介紹了IOS開發(fā)OC代碼中創(chuàng)建Swift編寫的視圖控制器的相關(guān)資料,需要的朋友可以參考下2017-06-06
iOS實(shí)現(xiàn)視頻壓縮上傳實(shí)例代碼
本篇文章主要介紹了iOS實(shí)現(xiàn)視頻壓縮上傳實(shí)例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-04-04
iOS AVCaptureSession實(shí)現(xiàn)視頻錄制功能
這篇文章主要為大家詳細(xì)介紹了iOS AVCaptureSession實(shí)現(xiàn)視頻錄制功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-05-05
通過UIKit坐標(biāo)系來全面掌握iOS中的UIScrollView組件
iOS開發(fā)套件中的UIScrollView組件十分強(qiáng)大,不僅是滾動,縮放操作也能夠控制自如,其核心當(dāng)然是坐標(biāo)軸上的控制,下面就通過UIKit坐標(biāo)系來全面掌握iOS中的UIScrollView組件2016-05-05

