flutter key的基本使用

flutter中萬物皆組件,組件皆有key,flutter開發是組件堆砌的,組件很多,能複用就複用,如果沒有一個標記,flutter做diff算法複用element的時候很容易數據錯亂,所以,key根本作用在這

key能解決大部分的問題,flutter能分清key對應的元素。但是別指望能解決所有的問題。下面逐個解析,綜合應用key解決所有問題

比如:

center(container(text("", key)))這種結構,使用和不使用center的情況下內部的text就複用不了了

Widget和ELement

widget是虛擬的,並不是實際渲染的那個東西

flutter中有widget tree,element tree,renderobject tree。widget tree可以理解爲藍圖,一個佈局頁面的工具,element tree管理狀態,上能訪問widget tree,下能關聯renderobject tree。

diff算法:flutter需要刷新頁面佈局的時候,會從要刷新的Element tree第一級逐級往下對比:widget tree 和 element tree對比,判斷類型是否改變 & 判斷key是否一致。如果有一個條件不滿足,就在當前widget tree同級別組件中找同類型同key的組件關聯

針對element tree在widget tree關聯不到的,會銷燬實例。widget tree中在element tree中沒有的,element tree會新建並關聯上

懂了這個複用流程後,上面說的那個有沒有center的情況就能解釋了。

局部鍵

ValueKey

flutter對比key的規則是值是否相等,這個可以自己重寫operator

class MyValueKey {
  String id;
  String key;

  MyValueKey(this.id, this.key);
  
  @override
  bool operator ==(Object other) =>
      identical(this, other) ||
      other is MyValueKey &&
          runtimeType == other.runtimeType &&
          id == other.id &&
          key == other.key;

  @override
  int get hashCode => id.hashCode ^ key.hashCode;
}

generate快速生成

ObjectKey

key的對比規則是對比key的內存地址,是否是同一個obj,而不是單單看值。跟java中的equals和==的區別差不多。

/// Check whether two references are to the same object.
///
/// Example:
/// ```dart
/// var o = new Object();
/// var isIdentical = identical(o, new Object()); // false, different objects.
/// isIdentical = identical(o, o); // true, same object
/// isIdentical = identical(const Object(), const Object()); // true, const canonicalizes
/// isIdentical = identical([1], [1]); // false
/// isIdentical = identical(const [1], const [1]); // true
/// isIdentical = identical(const [1], const [2]); // false
/// isIdentical = identical(2, 1 + 1); // true, integers canonicalizes
/// ```
external bool identical(Object? a, Object? b);

UniqueKey

組件每次刷新時候,UniqueKey都會是新的,這種key用的不多,可以理解一下下面的代碼場景:

    return Center(
      child: AnimatedSwitcher(
        duration: const Duration(seconds: 1),
        child: Text("content", key: UniqueKey(),),
      ),
    );

這種應用,當content有變化的時候會有動畫過渡。每次content有變動觸發刷新,uniqueKey都不一樣,text就會新建

全局鍵

上面有說當使用局部鍵的時候,如果widget tree層級有變化,那麼狀態就會丟失,但是這種情況怎麼解決呢?

可以使用GlobalKey,跟普通的key使用一樣

注意:

1、globalKey在app中是唯一的,一個GlobalKey實例只能給一個組件使用。所以,需要幾個實例化幾個

根據globalKey找組件

前端:document.getElementById

iOS:getViewWithTag

android:findViewById

應用都差不多

_globalKey.currentState as yourWidgetState

_globalKey.currentWidget as yourWidget

_globalKey.currentContext as RenderBox
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章