源碼解讀
/// 這是描述 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ù)。