Flutter之InheritedWidget的妙用
在看文章前,先想下這幾個問題:
- 問題1. 在一個widget中如何讓子widget也得到這個widget的屬性呢?比如MaterialApp中theme主題屬性,如何讓子widget也可以得到使用theme呢?
- 問題2 . InheritedWidget該如何使用呢?注意什麼?跟狀態管理有什麼不同?
InheritedWidget的理解
從Inherited字面可以得知它是繼承的一個widget,那什麼是繼承呢?學過面向對象都知道,如果一個父類對象有的屬性,通過繼承子類對象也有這個屬性。那在flutter中也是差不多的,由於flutter基本上都是一層套一層的創建對象傳遞參數,想要讓子類持有父類的屬性變量變得有點難處理,於是InheritedWidget出來就來解決這個問題了。
說了這麼多,就是一句話:可以有效的將數據在當前Widget中的子Widget中傳遞下去。
創建
- 寫個類繼承InheritedWidget,重寫updateShouldNotify
- 寫要存儲的變量以及對應的構造方法
class ShareWidget extends InheritedWidget{
//存儲的變量
final int data;//可以是類,可以簡單類型
///構造函數
const ShareWidget({Key key,@required this.data,@required Widget child}) : super(key: key,child: child);
///framework通過使用舊widget佔據樹中的這個位置的小部件作爲參數調用這個函數來區分這些情況。
@override
bool updateShouldNotify(ShareWidget oldWidget) {
return oldWidget.data != data;//一般比較的是數據是不是不一樣
}
}
使用
使用的使用一定在需要獲取屬性的widget最頂部使用,這樣子widget才能獲取到,絕對不能是兄弟關係,
獲取
//定義一個方法,方便子樹中的widget獲取這個widget,進而獲得共享數據。
static ShareWidget of(BuildContext context){
/**
* 獲取最近的給定類型的Widget,該widget必須是InheritedWidget的子類,
* 並向該widget註冊傳入的context,當該widget改變時,
* 這個context會重新構建以便從該widget獲得新的值。
* 這就是child向InheritedWidget註冊的方法。
*/
return context.inheritFromWidgetOfExactType(ShareWidget);
}
狀態數據
我項目中使用provider,可以看下provider的源碼核心也是使用這個類來達到數據共享的,
可以看到InheritedProvider也是繼承的InheritedWidget,更爲高級的是使用了泛型,這樣的好處可以支持的類型更多了,兼容性和擴展性更強。