網站首頁 編程語言 正文
引子
管理對象太多?
刷新管理太麻煩 ?
Flutter刷新范圍控制不好 ?
不妨看看本文 , 希望提供給你一些思路吧 !
說起 Flutter 刷新, 你的第一印象是什么 ? setState ? 是的, 只要使用過 Flutter 的人, 第一印象都必然是 setState , 但是由于 setState 濫用的問題, 性能問題就脫穎而出.
因此產出了諸如 Fish_redux 之流, 這些框架盡可能的使用 StatelessWidget 而由框架本身來引導刷新. 那么, 我們除了框架, 有沒有辦法來控制 Flutter 的刷新呢?
ValueListenableBuilder
ValueListenableBuilder 是基于 Flutter 自身特點構建的一個 widget. 它借助了觀察者模式 , 高效率的引導 Flutter 框架來刷新指定位置. 在繁雜的界面中, 細粒化的更新特定的 widget. 我們接下來, 舉例子并分析一下它是如何用,怎么做的吧!
如何用
這里我們通過一個簡單的例子 - 計數器, 它的作用是每點擊一次按鈕, 數字便會增加一.
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. 記錄下點擊十次后, 整體界面的刷新次數.
結果上, 我們發現了整體頁面的每個組件都刷新了十次. 我們再通過 ValueListenableBuilder 來重構頁面, 并同樣刷新十次
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沒有再刷新. 因此, 我們可以推斷出層級越深、組件越多, 我們優化的效果也就越明顯
那么, 這是怎么做到的呢 ? 讓我們來一起探究一下 .
怎么做
ValueListenableBuilder 是一個 StatefulWidget. 也就是說它具備刷新的能力, 它通過監聽 ValueListenable 對象的變換.我們將目光轉到它的 State 中. 在 initState 中 , 也就是最初加載這個 widget 的時候. 我們初始化了 value 的值, 并且增加了一個監聽.
@override
void initState() {
super.initState();
value = widget.valueListenable.value;
widget.valueListenable.addListener(_valueChanged);
}
在這個監聽中, 我們發現只要 valueListenable 的值發生變化, 便會立即通知當前 state 刷新. 因此它的刷新范圍只限制于局部.
void _valueChanged() {
setState(() { value = widget.valueListenable.value; });
}
同時, 它在外部可能刷新修改 valueListenable 對象的時候, 移除了之前的監聽. 并增加了新的監聽對象. 其余的步驟還是和之前一樣.
@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);
}
}
通過這一系列的操作, Flutter 實現了點對點的刷新方案.
不足點
雖然 ValueListenableBuilder 已經解決了大部分刷新場景需要定向刷新的需求, 但是它刷新的顆粒度還不夠. 如果我們針對每個 widget 都需要不同的對象通知更新, 那么, 我們就要自己手動創建 N 個通知者, 這給開發帶來了難以預料的維護難度. 因此, 在實際運用的場景中, 我們更偏向于單個不與其他業務接觸的業務或者一個自行維護的widget. 盡可能減少業務復雜度. 為了解決這種問題, Getx、Bloc、Provider都算比較好的狀態管理框架.
原文鏈接:https://juejin.cn/post/7175727975055228989
相關推薦
- 2022-11-14 基于統計自適應線性回歸-目標尺寸預測
- 2022-08-31 ASP.NET?Core的日志系統介紹_實用技巧
- 2022-11-27 使用Docker搭建Apache?Kafka環境的詳細過程_docker
- 2022-05-14 面試分析分布式架構Redis熱點key大Value解決方案_Redis
- 2022-04-28 C語言動態開辟內存詳解_C 語言
- 2022-05-24 C語言的strcpy函數你了解嗎_C 語言
- 2022-07-10 手動實現function isInstanceOf(child,Parent)
- 2022-01-16 meteor node node-gyp bindings.node dll報錯解決方案
- 最近更新
-
- 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同步修改后的遠程分支