Flutter最小刷新范圍探索ValueListenableBuilder使用詳解
引子
管理對(duì)象太多?
刷新管理太麻煩 ?
Flutter刷新范圍控制不好 ?
不妨看看本文 , 希望提供給你一些思路吧 !
說(shuō)起 Flutter 刷新, 你的第一印象是什么 ? setState ? 是的, 只要使用過(guò) Flutter 的人, 第一印象都必然是 setState , 但是由于 setState 濫用的問(wèn)題, 性能問(wèn)題就脫穎而出.
因此產(chǎn)出了諸如 Fish_redux 之流, 這些框架盡可能的使用 StatelessWidget 而由框架本身來(lái)引導(dǎo)刷新. 那么, 我們除了框架, 有沒有辦法來(lái)控制 Flutter 的刷新呢?
ValueListenableBuilder
ValueListenableBuilder 是基于 Flutter 自身特點(diǎn)構(gòu)建的一個(gè) widget. 它借助了觀察者模式 , 高效率的引導(dǎo) Flutter 框架來(lái)刷新指定位置. 在繁雜的界面中, 細(xì)?;母绿囟ǖ?widget. 我們接下來(lái), 舉例子并分析一下它是如何用,怎么做的吧!
如何用
這里我們通過(guò)一個(gè)簡(jiǎn)單的例子 - 計(jì)數(shù)器, 它的作用是每點(diǎn)擊一次按鈕, 數(shù)字便會(huì)增加一.
Scaffold(
body: Center(
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(num.toString()),
IconButton(
color: Colors.blue,
onPressed: () {
if (mounted) {
setState(() {
num++;
});
}
},
icon: const Icon(Icons.add),
),
],
),
),
)

我們打開Android studio 自帶的工具 Flutter Performance , 打開 Track widget rebuilds. 記錄下點(diǎn)擊十次后, 整體界面的刷新次數(shù).

結(jié)果上, 我們發(fā)現(xiàn)了整體頁(yè)面的每個(gè)組件都刷新了十次. 我們?cè)偻ㄟ^(guò) ValueListenableBuilder 來(lái)重構(gòu)頁(yè)面, 并同樣刷新十次
final ValueNotifier<int> notifier = ValueNotifier(0);
Scaffold{
body: Column{
...
children: [
ValueListenableBuilder<int>(
valueListenable: notifier,
builder: (BuildContext context, value, Widget? child) {
return Text(
value.toString(),
style: const TextStyle(fontSize: 20),
);
},
),
...
]
}
}
這次我們可以看到,除了 ValueListenableBuilder 和 Text 本身刷新了十次, 其余的 widget沒有再刷新. 因此, 我們可以推斷出層級(jí)越深、組件越多, 我們優(yōu)化的效果也就越明顯
那么, 這是怎么做到的呢 ? 讓我們來(lái)一起探究一下 .

怎么做
ValueListenableBuilder 是一個(gè) StatefulWidget. 也就是說(shuō)它具備刷新的能力, 它通過(guò)監(jiān)聽 ValueListenable 對(duì)象的變換.我們將目光轉(zhuǎn)到它的 State 中. 在 initState 中 , 也就是最初加載這個(gè) widget 的時(shí)候. 我們初始化了 value 的值, 并且增加了一個(gè)監(jiān)聽.
@override
void initState() {
super.initState();
value = widget.valueListenable.value;
widget.valueListenable.addListener(_valueChanged);
}
在這個(gè)監(jiān)聽中, 我們發(fā)現(xiàn)只要 valueListenable 的值發(fā)生變化, 便會(huì)立即通知當(dāng)前 state 刷新. 因此它的刷新范圍只限制于局部.
void _valueChanged() {
setState(() { value = widget.valueListenable.value; });
}
同時(shí), 它在外部可能刷新修改 valueListenable 對(duì)象的時(shí)候, 移除了之前的監(jiān)聽. 并增加了新的監(jiān)聽對(duì)象. 其余的步驟還是和之前一樣.
@override
void didUpdateWidget(ValueListenableBuilder<T> oldWidget) {
super.didUpdateWidget(oldWidget);
if (oldWidget.valueListenable != widget.valueListenable) {
oldWidget.valueListenable.removeListener(_valueChanged);
value = widget.valueListenable.value;
widget.valueListenable.addListener(_valueChanged);
}
}
通過(guò)這一系列的操作, Flutter 實(shí)現(xiàn)了點(diǎn)對(duì)點(diǎn)的刷新方案.
不足點(diǎn)
雖然 ValueListenableBuilder 已經(jīng)解決了大部分刷新場(chǎng)景需要定向刷新的需求, 但是它刷新的顆粒度還不夠. 如果我們針對(duì)每個(gè) widget 都需要不同的對(duì)象通知更新, 那么, 我們就要自己手動(dòng)創(chuàng)建 N 個(gè)通知者, 這給開發(fā)帶來(lái)了難以預(yù)料的維護(hù)難度. 因此, 在實(shí)際運(yùn)用的場(chǎng)景中, 我們更偏向于單個(gè)不與其他業(yè)務(wù)接觸的業(yè)務(wù)或者一個(gè)自行維護(hù)的widget. 盡可能減少業(yè)務(wù)復(fù)雜度. 為了解決這種問(wèn)題, Getx、Bloc、Provider都算比較好的狀態(tài)管理框架.
以上就是Flutter最小刷新范圍探索ValueListenableBuilder使用詳解的詳細(xì)內(nèi)容,更多關(guān)于Flutter ValueListenableBuilder的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Android實(shí)現(xiàn)合并生成分享圖片功能
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)合并生成分享圖片功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-03-03
Android實(shí)現(xiàn)動(dòng)態(tài)定值范圍效果的控件
這篇文中給大家分享一個(gè)Android的控件,這個(gè)控件實(shí)現(xiàn)是一個(gè)可以動(dòng)態(tài)選擇定值范圍的效果,實(shí)現(xiàn)后的效果很不錯(cuò),對(duì)大家日常開發(fā)或許有所幫助,感興趣的朋友們可以一起來(lái)看看。2016-09-09
Android PC端用ADB抓取指定應(yīng)用日志實(shí)現(xiàn)步驟
這篇文章主要介紹了Android PC端用ADB抓取指定應(yīng)用日志實(shí)現(xiàn)步驟,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-04-04
Android保存多張圖片到本地的實(shí)現(xiàn)方法
這篇文章主要給大家介紹了關(guān)于Android保存多張圖片到本地的實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)各位Android開發(fā)者們具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-06-06
詳解Flutter 調(diào)用 Android Native 的方法
這篇文章主要介紹了詳解Flutter 調(diào)用 Android Native 的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01
android 實(shí)現(xiàn)控件左右或上下抖動(dòng)教程
這篇文章主要介紹了android 實(shí)現(xiàn)控件左右或上下抖動(dòng)教程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-03-03
Android實(shí)現(xiàn)帶磁性的懸浮窗體效果
這篇文章主要介紹了Android實(shí)現(xiàn)帶磁性的懸浮窗體效果,涉及Android針對(duì)窗體的動(dòng)態(tài)操作相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2016-07-07
NestedScrollView+Recyclerview下滑卡頓解決方法
本文為大家解決安卓開發(fā)時(shí)候NestedScrollView+Recyclerview下滑卡頓的問(wèn)題,希望能夠幫助到你。2017-11-11
用Android MenuInflater創(chuàng)建菜單項(xiàng)的方法步驟
本篇文章小編為大家介紹,用Android MenuInflater創(chuàng)建菜單項(xiàng)的方法步驟。需要的朋友參考下2013-04-04

