網站首頁 編程語言 正文
一、痛點
痛點一:Flutter
官方提供了 ScrollController
,調用下方兩個方法可以滾動到指定偏移處
void jumpTo(double value)
Future<void> animateTo( double offset, { required Duration duration, required Curve curve, })
但是官方沒有提供滾動到指定下標位置的功能
痛點二:
為了解決痛點一,業內有很多第三方庫實現了這個功能,其中最知名的莫過于谷歌的 scrollable_positioned_list
而這些庫都有一些相同的問題:
- 侵入性強,必須使用他們提供的
Widget
來構建列表視圖 - 不支持
GridView
對此,我決定自己編寫一個庫(flutter_scrollview_observer)來實現這個功能,以及解決以上的問題。
二、優點
- 侵入性低,不會限制你的列表視圖實現,只要求將列表視圖做為
ViewObserver
的child
,如果不想用了,直接移除掉ViewObserver
即可。 - 基于【不會限制你的列表視圖實現】這一點,
flutter_scrollview_observer
支持所有的列表Widget
,如:ListView
、GridView
,甚至CustomSrollView
- 防抖動,如果在滾動到指定下標時,列表尾部的可滾動區域已不足以支撐滾動到相應位置,則會自動滾動到最底部,避免回彈的問題
下面正式介紹一下這個庫的使用
三、使用
1、ListView
正常創建和使用 ScrollController
實例
這里你可以使用 ListView
或者 CustomSrollView
的 SliverList
ScrollController scrollController = ScrollController(); ListView _buildListView() { return ListView.separated( controller: scrollController, ... ); }
創建 ListObserverController
實例并將其傳遞給 ListViewObserver
ListObserverController observerController = ListObserverController(controller: scrollController); ListViewObserver( controller: observerController, child: _buildListView(), ... )
注意:創建 ListObserverController
實例時需要傳入列表的 ScrollController
實例。 這一步很重要,因為 flutter_scrollview_observer
內部實現原理是基于官方 ScrollController
提供的 jumpTo
和 animateTo
方法
現在即可滾動到指定下標位置了
// 無動畫滾動至下標位置 observerController.jumpTo(index: 100) // 動畫滾動至下標位置 observerController.animateTo( index: 100, duration: const Duration(seconds: 1), curve: Curves.ease, );
2、GridView
內容與 ListView
基本一致
正常創建和使用 ScrollController
實例
Widget _buildGridView() { return GridView.builder( ... controller: scrollController, ... ); }
創建 GridObserverController
實例并將其傳遞給 GridViewObserver
GridObserverController observerController = GridObserverController(controller: scrollController); GridViewObserver( controller: observerController, child: _buildGridView(), )
現在即可滾動到指定下標位置了
observerController.jumpTo( index: 40, ); observerController.animateTo( index: 40, duration: const Duration(seconds: 1), curve: Curves.ease, );
3、CustomSrollView
支持 SliverList
和 SliverGrid
混合使用的情況!
如上圖所示,CustomSrollView
的 slivers
中包含有 SliverList
和 SliverGrid
- 點擊右下角第一個按鈕可滾動到
SliverList
的第29
行 - 點擊第二個按鈕可滾動到
SliverGrid
的第10
的子部件所在行
正常創建和使用 ScrollController
實例
Widget _buildScrollView() { return CustomScrollView( controller: scrollController, // scrollDirection: Axis.horizontal, slivers: [ _buildSliverListView(), _buildSliverGridView(), ], ); }
正常創建你的 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; ... }, ... ), ); }
創建 SliverObserverController
實例并將其傳遞給 SliverViewObserver
注意:在 sliverListContexts
里返回剛才記錄的兩個 Sliver
的 BuildContext
SliverObserverController observerController = SliverObserverController(controller: scrollController); SliverViewObserver( controller: observerController, child: _buildScrollView(), sliverListContexts: () { return [ if (_sliverListCtx != null) _sliverListCtx!, if (_sliverGridCtx != null) _sliverGridCtx!, ]; }, ... ),
現在即可滾動到指定下標位置了
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 的選擇
建議使用相應的 ViewObserver
:
- 如果是
ListView
或者純SliverList
,建議使用ListViewObserver
- 如果是
GridView
或者純SliverGrid
,建議使用GridViewObserver
- 如果是
SliverList
和SliverGrid
,則使用SliverViewObserver
這樣在 onObserve
回調中拿到數據模型后不用再對其進行類型判斷與轉換。
2、isFixedHeight
子部件為固定高度的情況下,請設置 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
參數,這是用來指定哪個 sliver
進行滾動操作的。
如果不傳 sliverContext
,則默認會是列表中的第一個 sliver
,只有你想讓非第一個 sliver
進行滾動的時候才需要傳該值
五、可現實的功能
1、獲得當前視窗中的子部件信息
如上圖控制臺所示,在滾動的過程中可以實時獲取正在顯示的子部件的數據。
2、視頻列表自動播放
這種功能很常見,在列表滾動的時候,指定區域內的被命中的視頻便會自動進行播放。
3、模塊定位
一般詳情頁中都會有的功能,在列表視圖滾動的時候,頂部定位導航視圖跟著更新下標,點擊導航視圖某個下標則會定位到對應的模塊
六、最后
如果這個庫對你很有幫助,請不吝給個 star
吧
GitHub: flutter_scrollview_observer
原文鏈接:https://juejin.cn/post/7129888644290068487
相關推薦
- 2022-03-14 spring junit 做單元測試,報 Failed to load ApplicationCon
- 2022-07-13 Python中常用序列數據結構
- 2022-07-09 基于fluttertoast實現封裝彈框提示工具類_Android
- 2022-09-20 C#單線程和多線程端口掃描器詳解_C#教程
- 2022-12-26 python?時間處理之月份加減問題_python
- 2022-06-01 C++程序內存棧區與堆區模型案例分析_C 語言
- 2022-08-30 如何解決React?useEffect鉤子帶來的無限循環問題_React
- 2024-04-08 Linux 服務器連接方式
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支