Flutter 中 key 的原理及作用
這是我參與11月更文挑戰的第13天,活動詳情檢視:2021最後一次更文挑戰
Key 的原理
static bool canUpdate(Widget oldWidget, Widget newWidget) {
return oldWidget.runtimeType == newWidget.runtimeType
&& oldWidget.key == newWidget.key;
}
如圖 1 所示,當我們生成一個 Widget
樹的時候也會對應生成 Element
樹,Widget
與 Element
一一對應。但是當我們移除 Widget1
的時候會呼叫 Element
的 canUpdate
方法,canUpdate
方法中會判斷舊的 Widget
與新的 Widget
的 runtimeType
是否相等,且 key
是否相等。當我們不使用 key
時候,就會預設它們相等,就會如圖 2 所示,Element1
就會比較 oldWidget.runtimeType == newWidget.runtimeType
,因為 Element1
曾經指向的型別與 Widget2
型別相同所以 Widget2
就會複用 Element1
,同理 Widget3
就會複用 Element2
,依次比較,當 Element3
沒有指向的時候就會被移除。所以 Key
的作用可以用來跟 Widget
做繫結,判斷 canUpdate
是否執行。
Key
本身是一個抽象類,有一個工廠程構造方法ValueKey()
。- 直接子類主要有:
LocalKey
跟GlobalKey
。LocalKey
是增量演算法的核心,決定哪個Element
要保留,哪個Element
要刪除。以下是LocalKey
的三個子類。ValueKey
:以值作為引數(數字、字串)ObjectKey
:以物件作為引數UniqueKey
:建立唯一標識GlobalKey
對應某一個Widget
或者State
或者Element
。
GlobalKey 的使用
``` class GlobalKeyDemo extends StatelessWidget { final GlobalKey<_ChildPageState> _globalKey = GlobalKey();
GlobalKeyDemo({Key? key}) : super(key: key);
@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('GlobalKeyDemo'), ), body: ChildPage(key: _globalKey,), floatingActionButton: FloatingActionButton( onPressed: () { // _globalKey.currentContext // _globalKey.currentWidget _globalKey.currentState?.setState(() { _globalKey.currentState?.data = '666'; _globalKey.currentState?.count++; }); }, child: const Icon(Icons.add), ), ); } }
class ChildPage extends StatefulWidget { const ChildPage({Key? key}) : super(key: key);
@override _ChildPageState createState() => _ChildPageState(); }
class _ChildPageState extends State
如案例所示,當 FloatingActionButton
中 onPressed
閉包函式執行的時候我們想修改 _ChildPageState
中 count
及 data
的值,我們可以在 GlobalKeyDemo
中定義 _globalKey = GlobalKey()
,在初始化 ChildPage
的時候把 _globalKey
作為引數傳遞。這時候我們可以通過 _globalKey.currentContext
、_globalKey.currentWidget
、_globalKey.currentState
獲取我們想拿到的部件,這裡我們通過 _globalKey.currentState
就能獲取到 _ChildPageState
修改 data
及 count
屬性,並呼叫 setState
方法。個人感受 Flutter
中的 GlobalKey
有點類似 iOS
中 UIView
的 tag
屬性,可以通過 tag
來獲取到對應的 UIView
控制元件。
- Swift String、Moya 原始碼解析及高階函式
- Flutter 中 key 的原理及作用
- Flutter 生命週期及渲染原理
- Flutter 仿寫微信搜尋頁
- Flutter 網路請求類封裝及搜尋框實現
- Flutter 佈局聊天列表頁及網路資料處理
- Flutter 通訊錄索引條完善及聊天資料配置
- Flutter 仿寫微信通訊錄頁面
- Flutter 仿寫微信發現、我的頁面
- Flutter 專案搭建及工程配置
- 常用 Widget 部件介紹及 Flutter 佈局方式
- Flutter 之 Widget 部件體驗
- Dart 基礎語法
- 記憶體管理-弱引用分析
- NSTimer 不釋放問題分析及解決