Flutter列表滾動(dòng)定位超強(qiáng)輔助庫(kù)使用示例詳解
一、痛點(diǎn)
痛點(diǎn)一:Flutter
官方提供了 ScrollController
,調(diào)用下方兩個(gè)方法可以滾動(dòng)到指定偏移處
void jumpTo(double value)
Future<void> animateTo( double offset, { required Duration duration, required Curve curve, })
但是官方?jīng)]有提供滾動(dòng)到指定下標(biāo)位置的功能
痛點(diǎn)二:
為了解決痛點(diǎn)一,業(yè)內(nèi)有很多第三方庫(kù)實(shí)現(xiàn)了這個(gè)功能,其中最知名的莫過(guò)于谷歌的 scrollable_positioned_list
而這些庫(kù)都有一些相同的問(wèn)題:
- 侵入性強(qiáng),必須使用他們提供的
Widget
來(lái)構(gòu)建列表視圖 - 不支持
GridView
對(duì)此,我決定自己編寫一個(gè)庫(kù)(flutter_scrollview_observer)來(lái)實(shí)現(xiàn)這個(gè)功能,以及解決以上的問(wèn)題。
二、優(yōu)點(diǎn)
- 侵入性低,不會(huì)限制你的列表視圖實(shí)現(xiàn),只要求將列表視圖做為
ViewObserver
的child
,如果不想用了,直接移除掉ViewObserver
即可。 - 基于【不會(huì)限制你的列表視圖實(shí)現(xiàn)】這一點(diǎn),
flutter_scrollview_observer
支持所有的列表Widget
,如:ListView
、GridView
,甚至CustomSrollView
- 防抖動(dòng),如果在滾動(dòng)到指定下標(biāo)時(shí),列表尾部的可滾動(dòng)區(qū)域已不足以支撐滾動(dòng)到相應(yīng)位置,則會(huì)自動(dòng)滾動(dòng)到最底部,避免回彈的問(wèn)題
下面正式介紹一下這個(gè)庫(kù)的使用
三、使用
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í)例時(shí)需要傳入列表的 ScrollController
實(shí)例。 這一步很重要,因?yàn)?flutter_scrollview_observer
內(nèi)部實(shí)現(xiàn)原理是基于官方 ScrollController
提供的 jumpTo
和 animateTo
方法
現(xiàn)在即可滾動(dòng)到指定下標(biāo)位置了
// 無(wú)動(dòng)畫(huà)滾動(dòng)至下標(biāo)位置 observerController.jumpTo(index: 100) // 動(dòng)畫(huà)滾動(dòng)至下標(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)在即可滾動(dòng)到指定下標(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)擊右下角第一個(gè)按鈕可滾動(dòng)到
SliverList
的第29
行 - 點(diǎn)擊第二個(gè)按鈕可滾動(dòng)到
SliverGrid
的第10
的子部件所在行
正常創(chuàng)建和使用 ScrollController
實(shí)例
Widget _buildScrollView() { return CustomScrollView( controller: scrollController, // scrollDirection: Axis.horizontal, slivers: [ _buildSliverListView(), _buildSliverGridView(), ], ); }
正常創(chuàng)建你的 SliverList
和 SliverGrid
,并將它們的 BuildContext
記錄起來(lái)
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
里返回剛才記錄的兩個(gè) Sliver
的 BuildContext
SliverObserverController observerController = SliverObserverController(controller: scrollController); SliverViewObserver( controller: observerController, child: _buildScrollView(), sliverListContexts: () { return [ if (_sliverListCtx != null) _sliverListCtx!, if (_sliverGridCtx != null) _sliverGridCtx!, ]; }, ... ),
現(xiàn)在即可滾動(dòng)到指定下標(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, );
四、說(shuō)明
1、ViewObserver 的選擇
建議使用相應(yīng)的 ViewObserver
:
- 如果是
ListView
或者純SliverList
,建議使用ListViewObserver
- 如果是
GridView
或者純SliverGrid
,建議使用GridViewObserver
- 如果是
SliverList
和SliverGrid
,則使用SliverViewObserver
這樣在 onObserve
回調(diào)中拿到數(shù)據(jù)模型后不用再對(duì)其進(jìn)行類型判斷與轉(zhuǎn)換。
2、isFixedHeight
子部件為固定高度的情況下,請(qǐng)?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
方法中都有一個(gè) sliverContext
參數(shù),這是用來(lái)指定哪個(gè) sliver
進(jìn)行滾動(dòng)操作的。
如果不傳 sliverContext
,則默認(rèn)會(huì)是列表中的第一個(gè) sliver
,只有你想讓非第一個(gè) sliver
進(jìn)行滾動(dòng)的時(shí)候才需要傳該值
五、可現(xiàn)實(shí)的功能
1、獲得當(dāng)前視窗中的子部件信息
如上圖控制臺(tái)所示,在滾動(dòng)的過(guò)程中可以實(shí)時(shí)獲取正在顯示的子部件的數(shù)據(jù)。
2、視頻列表自動(dòng)播放
這種功能很常見(jiàn),在列表滾動(dòng)的時(shí)候,指定區(qū)域內(nèi)的被命中的視頻便會(huì)自動(dòng)進(jìn)行播放。
3、模塊定位
一般詳情頁(yè)中都會(huì)有的功能,在列表視圖滾動(dòng)的時(shí)候,頂部定位導(dǎo)航視圖跟著更新下標(biāo),點(diǎn)擊導(dǎo)航視圖某個(gè)下標(biāo)則會(huì)定位到對(duì)應(yīng)的模塊
六、最后
如果這個(gè)庫(kù)對(duì)你很有幫助,請(qǐng)不吝給個(gè) star
吧
GitHub: flutter_scrollview_observer
以上就是Flutter列表滾動(dòng)定位超強(qiáng)輔助庫(kù)使用示例詳解的詳細(xì)內(nèi)容,更多關(guān)于Flutter列表滾動(dòng)定位輔助庫(kù)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
IOS開(kāi)發(fā)OC代碼中創(chuàng)建Swift編寫的視圖控制器
這篇文章主要介紹了IOS開(kāi)發(fā)OC代碼中創(chuàng)建Swift編寫的視圖控制器的相關(guān)資料,需要的朋友可以參考下2017-06-06詳解Objective-C中的語(yǔ)法糖@{}究竟是什么
這篇文章主要給大家介紹了關(guān)于Objective-C中語(yǔ)法糖@{}究竟是什么的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04IOS等待時(shí)動(dòng)畫(huà)效果的實(shí)現(xiàn)
查詢時(shí)間有長(zhǎng)有短,為了增強(qiáng)用戶體驗(yàn)度,目前用的比較多的手段之一是查詢等待時(shí)添加一個(gè)動(dòng)態(tài)等待效果,這篇文章主要介紹IOS等待時(shí)動(dòng)畫(huà)效果的實(shí)現(xiàn),有需要的朋友可以參考下2015-08-08淺談iOS關(guān)于頭文件的導(dǎo)入問(wèn)題
本篇文章主要介紹了淺談iOS關(guān)于頭文件的導(dǎo)入問(wèn)題,具有一定的參考價(jià)值,有興趣的可以了解一下。2017-04-04iOS實(shí)現(xiàn)視頻壓縮上傳實(shí)例代碼
本篇文章主要介紹了iOS實(shí)現(xiàn)視頻壓縮上傳實(shí)例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-04-04iOS AVCaptureSession實(shí)現(xiàn)視頻錄制功能
這篇文章主要為大家詳細(xì)介紹了iOS AVCaptureSession實(shí)現(xiàn)視頻錄制功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-05-05通過(guò)UIKit坐標(biāo)系來(lái)全面掌握iOS中的UIScrollView組件
iOS開(kāi)發(fā)套件中的UIScrollView組件十分強(qiáng)大,不僅是滾動(dòng),縮放操作也能夠控制自如,其核心當(dāng)然是坐標(biāo)軸上的控制,下面就通過(guò)UIKit坐標(biāo)系來(lái)全面掌握iOS中的UIScrollView組件2016-05-05