Flutter獲取ListView當(dāng)前正在顯示的Widget信息(應(yīng)用場(chǎng)景)
一、概述
Flutter
中的 ListView
相信大家都用的很熟了,不過有沒有人遇到過一些這樣的需求:
- 詳情頁(yè)滾動(dòng)到某一指定模塊后,停止?jié)L動(dòng)并根據(jù)該指定模塊的大小彈出全屏新手引導(dǎo)
- 詳情頁(yè)在滾動(dòng)過程中,頂部的模塊定位導(dǎo)航欄需要及時(shí)更新指示器下標(biāo)
- 視頻列表在滾動(dòng)過程中,適當(dāng)位置的子部件會(huì)自動(dòng)進(jìn)行播放視頻
- 等等
在日常開發(fā)過程中這種類似的功能需求還是蠻多的,因此我封裝了一個(gè)庫(kù):flutter_scrollview_observer
相信可以很好的幫助大家解決這些問題 ??
二、應(yīng)用場(chǎng)景
下面我們來看看常見的應(yīng)用場(chǎng)景:
1、獲取最頂部的子部件信息
可以獲取當(dāng)前的第一個(gè)子部件和所有正在顯示的子部件信息
2、視頻列表自動(dòng)播放
當(dāng)子部件進(jìn)入列表中間區(qū)域時(shí),自動(dòng)播放視頻
3、模塊定位
當(dāng)滾動(dòng)到一些特定模塊時(shí),頂部的 TabBar
的指示器切換到對(duì)應(yīng)模塊 tab
三、使用
1、基本使用
創(chuàng)建ListView
,并在其builder
回調(diào)中,將 SliverListView
的BuildContext
記錄起來
BuildContext? _sliverListViewContext; ... ListView _buildListView() { return ListView.separated( itemBuilder: (ctx, index) { // 在 builder 回調(diào)中,將 BuildContext 記錄起來 if (_sliverListViewContext != ctx) { _sliverListViewContext = ctx; } return _buildListItemView(index); }, separatorBuilder: (ctx, index) { return _buildSeparatorView(); }, itemCount: 50, ); }
注:在使用過程中,需要記錄
SliverListView
的BuildContext
,ListView
最終也是使用SliverListView
來進(jìn)行布局的
構(gòu)建ListViewObserver
child
: 將構(gòu)建的ListView
做為ListViewObserver
的子部件sliverListContexts
: 該回調(diào)中需要返回被觀察的ListView
的BuildContext
onObserve
: 該回調(diào)可以監(jiān)聽到當(dāng)前正在顯示的子部件的相關(guān)信息
ListViewObserver( child: _buildListView(), sliverListContexts: () { return [if (_sliverListViewContext != null) _sliverListViewContext!]; }, onObserve: (resultMap) { final model = resultMap[_sliverListViewContext]; if (model == null) return; // 打印當(dāng)前正在顯示的第一個(gè)子部件 print('firstChild.index -- ${model.firstChild.index}'); // 打印當(dāng)前正在顯示的所有子部件下標(biāo) print('displaying -- ${model.displayingChildIndexList}'); }, )
除了上述幾個(gè)常用參數(shù)外,還有:
leadingOffset
:頂部偏移,當(dāng)列表的視窗會(huì)固定被其它視圖擋住時(shí)使用dynamicLeadingOffset
:動(dòng)態(tài)頂部偏移,當(dāng)列表的視窗會(huì)動(dòng)態(tài)被其它視圖擋住時(shí)使用
這里看一下圖就明白了
// 導(dǎo)航欄半透明 flutter: firstChild.index -- 0 flutter: displaying -- [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] flutter: firstChild.index -- 0 flutter: displaying -- [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] // 導(dǎo)航欄完全不透明 flutter: firstChild.index -- 2 flutter: displaying -- [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
滾動(dòng)過程會(huì)改變頂部的導(dǎo)航欄透明度,在這個(gè)前提下:
- 當(dāng)半透明時(shí),我們希望列表的所有可見子部件從最頂部開始算起
- 當(dāng)完成不透明時(shí),我們希望列表的所有可見子部件從導(dǎo)航欄底部開始算起
ListViewObserver( ... dynamicLeadingOffset: () { if (_navBgAlpha < 1) { return 0; } return _safeAreaPaddingTop + _navContentHeight; }, ... ),
toNextOverPercent
:內(nèi)部邏輯在取到第一個(gè)子部件后,如果該子部件被擋住的大小與自身大小的比例超過了該值,則會(huì)取下一個(gè)子部件為第一個(gè)子部件。
2、手動(dòng)觸發(fā)
默認(rèn)是ListView
在滾動(dòng)的時(shí)候才會(huì)觀察到相關(guān)數(shù)據(jù)。
如果需要在非滾動(dòng)狀態(tài)下進(jìn)行一次觀察,可以使用ListViewOnceObserveNotification
進(jìn)行手動(dòng)觸發(fā)
ListViewOnceObserveNotification().dispatch(_sliverListViewContext);
注:如果頻繁觸發(fā),且觀察結(jié)果相同,則
onObserve
只會(huì)回調(diào)一次
3、子部件信息
觀察到的模型數(shù)據(jù):
class ListViewObserveModel { /// 第一個(gè)子部件模型數(shù)據(jù) final ListViewObserveDisplayingChildModel firstChild; /// 正在顯示的所有子部件模型數(shù)據(jù) final List<ListViewObserveDisplayingChildModel> displayingChildModelList; /// 正在顯示的所有子部件下標(biāo) List<int> get displayingChildIndexList => displayingChildModelList.map((e) => e.index).toList(); }
子部件模型數(shù)據(jù):
class ListViewObserveDisplayingChildModel { /// 子部件下標(biāo) final int index; /// 子部件的 RenderObject final RenderBox renderObject; }
GitHub: LinXunFeng/flutter_scrollview_observer
到此這篇關(guān)于Flutter獲取ListView當(dāng)前正在顯示的Widget信息的文章就介紹到這了,更多相關(guān)Flutter獲取當(dāng)前Widget信息內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Android?flutter?Dio鎖的巧妙實(shí)現(xiàn)方法示例
這篇文章主要為大家介紹了Android?flutter?Dio鎖的巧妙實(shí)現(xiàn)方法示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01使用Android自定義控件實(shí)現(xiàn)滑動(dòng)解鎖九宮格
最近由于Android項(xiàng)目需要,要求做一個(gè)類似于支付寶的九宮格解鎖組件,下面小編給大家分享了具體實(shí)現(xiàn)代碼,需要的朋友可以參考下2015-10-10Android sqlite設(shè)置主鍵自增長(zhǎng)的方法教程
這篇文章主要給大家介紹了關(guān)于Android sqlite設(shè)置主鍵自增長(zhǎng)的方法教程,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面跟著小編一起來學(xué)習(xí)學(xué)習(xí)吧。2017-06-06Android使用GridView實(shí)現(xiàn)表格分割線效果
這篇文章主要為大家詳細(xì)介紹了Android使用GridView實(shí)現(xiàn)表格分割線效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-07-07Android添加ButterKnife時(shí)報(bào)錯(cuò)Error:(2, 0) Cannot add extension wit
今天小編就為大家分享一篇關(guān)于Android添加ButterKnife時(shí)報(bào)錯(cuò)Error:(2, 0) Cannot add extension with name 'android'的解決辦法,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2018-12-12Android中使用自定義ViewGroup的總結(jié)
本篇文章主要介紹了Android中使用自定義ViewGroup的總結(jié),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-01-01基于標(biāo)準(zhǔn)http實(shí)現(xiàn)Android多文件上傳
這篇文章主要介紹了基于標(biāo)準(zhǔn)http實(shí)現(xiàn)Android多文件上傳的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-01-01Android學(xué)習(xí)之AppWidget筆記分享
這篇文章主要為大家詳細(xì)介紹了Android學(xué)習(xí)筆記之AppWidget的相關(guān)資料,感興趣的小伙伴們可以參考一下2016-08-08Android貝塞爾曲線初步學(xué)習(xí)第三課 Android實(shí)現(xiàn)添加至購(gòu)物車的運(yùn)動(dòng)軌跡
這篇文章主要為大家詳細(xì)介紹了Android貝塞爾曲線初步學(xué)習(xí)第三課,Android實(shí)現(xiàn)添加至購(gòu)物車的運(yùn)動(dòng)軌跡,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-03-03