Flutter獲取ListView當(dāng)前正在顯示的Widget信息(應(yīng)用場(chǎng)景)
一、概述
Flutter 中的 ListView 相信大家都用的很熟了,不過(guò)有沒(méi)有人遇到過(guò)一些這樣的需求:
- 詳情頁(yè)滾動(dòng)到某一指定模塊后,停止?jié)L動(dòng)并根據(jù)該指定模塊的大小彈出全屏新手引導(dǎo)
- 詳情頁(yè)在滾動(dòng)過(guò)程中,頂部的模塊定位導(dǎo)航欄需要及時(shí)更新指示器下標(biāo)
- 視頻列表在滾動(dòng)過(guò)程中,適當(dāng)位置的子部件會(huì)自動(dòng)進(jìn)行播放視頻
- 等等
在日常開發(fā)過(guò)程中這種類似的功能需求還是蠻多的,因此我封裝了一個(gè)庫(kù):flutter_scrollview_observer
相信可以很好的幫助大家解決這些問(wèn)題 ??
二、應(yīng)用場(chǎng)景
下面我們來(lái)看看常見的應(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記錄起來(lái)
BuildContext? _sliverListViewContext;
...
ListView _buildListView() {
return ListView.separated(
itemBuilder: (ctx, index) {
// 在 builder 回調(diào)中,將 BuildContext 記錄起來(lái)
if (_sliverListViewContext != ctx) {
_sliverListViewContext = ctx;
}
return _buildListItemView(index);
},
separatorBuilder: (ctx, index) {
return _buildSeparatorView();
},
itemCount: 50,
);
}注:在使用過(guò)程中,需要記錄
SliverListView的BuildContext,ListView最終也是使用SliverListView來(lái)進(jìn)行布局的
構(gòu)建ListViewObserver
child: 將構(gòu)建的ListView做為ListViewObserver的子部件sliverListContexts: 該回調(diào)中需要返回被觀察的ListView的BuildContextonObserve: 該回調(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)過(guò)程會(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è)子部件后,如果該子部件被擋住的大小與自身大小的比例超過(guò)了該值,則會(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-10
Android sqlite設(shè)置主鍵自增長(zhǎng)的方法教程
這篇文章主要給大家介紹了關(guān)于Android sqlite設(shè)置主鍵自增長(zhǎng)的方法教程,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面跟著小編一起來(lái)學(xué)習(xí)學(xué)習(xí)吧。2017-06-06
Android使用GridView實(shí)現(xiàn)表格分割線效果
這篇文章主要為大家詳細(xì)介紹了Android使用GridView實(shí)現(xiàn)表格分割線效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-07-07
Android添加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'的解決辦法,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2018-12-12
Android中使用自定義ViewGroup的總結(jié)
本篇文章主要介紹了Android中使用自定義ViewGroup的總結(jié),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧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-01
Android學(xué)習(xí)之AppWidget筆記分享
這篇文章主要為大家詳細(xì)介紹了Android學(xué)習(xí)筆記之AppWidget的相關(guān)資料,感興趣的小伙伴們可以參考一下2016-08-08
Android貝塞爾曲線初步學(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

