Widget

源碼解讀

///  這是描述 Element 的配置

///  此小部件本身不可變的,如果想使用可變的,可以使用 StatefulWidget 小部件

///  該小部件可以被包含零次或者多次
///
/// [key] 屬性控制一個(gè)小部件如何替換樹中的另一個(gè)小部件。 如果兩個(gè)小部件的 [runtimeType] 和 [key] 屬性分別為 [operator==],
//  則新小部件通過(guò)更新底層元素來(lái)替換舊小部件(即,通過(guò)使用新小部件調(diào)用 [Element.update] )。 
//  否則,從樹中刪除舊元素,將新小部件膨脹為一個(gè)元素,并將新元素插入樹中。 

///  immutable 該部件是不可變的
@immutable
// Widget 繼承于 DiagnosticableTree 
abstract class Widget extends DiagnosticableTree {
  /// 初始化
  const Widget({ this.key });

  ///  控制一個(gè)小部件如何替換樹中的另一個(gè)小部件
  ///
  /// 如果兩個(gè)widget的[runtimeType]和[key]屬性分別為[operator==],
  /// 那么新widget通過(guò)更新底層元素替換舊widget(即通過(guò)調(diào)用[Element.update] 新的小部件)。 
  /// 否則,從樹中刪除舊元素,將新小部件膨脹為一個(gè)元素,并將新元素插入樹中。
  ///
  /// 另外,使用 [GlobalKey] 作為小部件的 [key] 允許元素在樹周圍移動(dòng)(更改父級(jí))而不會(huì)丟失狀態(tài)。 
  /// 當(dāng)找到一個(gè)新的小部件(它的鍵和類型與同一位置的前一個(gè)小部件不匹配),但在前一幀的樹中的      
  /// 其他地方有一個(gè)具有相同全局鍵的小部件,則該小部件的元素被移動(dòng)到新位置。
  final Key? key;

  ///  創(chuàng)建 Element 對(duì)象
  @protected
  @factory
  Element createElement();

  /// 該部件的簡(jiǎn)短描述
  @override
  String toStringShort() {
    // 獲取 Widget 運(yùn)行時(shí)的類型字符串
    final String type = objectRuntimeType(this, 'Widget');
    // 在沒有設(shè)置 key 時(shí),返回 type ,否者返回 type 和 key 組成的字符串
    return key == null ? type : '$type-$key';
  }
  
  /// 調(diào)試模式,部件屬性的填充
  @override
  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
    super.debugFillProperties(properties);
    properties.defaultDiagnosticsTreeStyle = DiagnosticsTreeStyle.dense;
  }

  @override
  /// 用于在類 `C` 或 mixin `M` 中注釋實(shí)例成員(方法、getter、setter、運(yùn)算符或字段)`m`。 
  /// 表示不應(yīng)在任何擴(kuò)展或混合“C”或“M”的類中覆蓋“m”。
  @nonVirtual 
  bool operator ==(Object other) => super == other;

  @override
  @nonVirtual
  /// 該部件的哈希碼
  int get hashCode => super.hashCode;

  ///  是否使用新的 newWidget 更換老的 oldWidget 的配置.
  ///
  /// 如果小部件沒有鍵(它們的鍵為空),那么如果它們具有相同的類型,
  /// 則認(rèn)為它們是匹配的,即使它們的孩子完全不同。
  static bool canUpdate(Widget oldWidget, Widget newWidget) {
    /// 舊的部件的運(yùn)行時(shí)類型和新的部件的運(yùn)行時(shí)類型相同,同時(shí)舊部件的key 和新部件的key 相同,才能更細(xì)部件
    return oldWidget.runtimeType == newWidget.runtimeType
        && oldWidget.key == newWidget.key;
  }

  // 返回特定 `Widget` 具體子類型的數(shù)字編碼。
  // 這在 `Element.updateChild` 中用于確定熱重載是否修改了已安裝元素配置的超類.
  static int _debugConcreteSubtype(Widget widget) {
    return widget is StatefulWidget ? 1 :
           widget is StatelessWidget ? 2 :
           0;
  }
}

二、總結(jié)

  • Widget 是 Flutter 部件的核心部件,一般常用 StatelessWidget 和StatefulWidget 兩種。
  • Widget 從 key 的有無(wú)和新舊部件更新的前提是新舊部件的 runTimeType 以及兩個(gè)部件的 key 是相等
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容