flutter InheritedWidget使用方法總結
引言
InheritedWidget,flutter中非常重要的一個功能組件。比如我們在應用的根 widget 中通過InheritedWidget共享了一個數據,那么我們便可以在任意子 widget 中來獲取該共享的數據。
didChangeDependencies
說到 InheritedWidget ,我們不得不聊聊 state 對象中的 didChangeDependencies 方法。當子控件依賴使用了父控件中的 InheritedWidget,比如主題、locale(語言)等發(fā)生變化時,依賴其的子 widget 的didChangeDependencies方法將會被調用。
一般來說,子 widget 很少會重寫此方法,因為在依賴改變后 framework 也都會調用build()方法。但是,如果你需要在依賴改變后執(zhí)行一些昂貴的操作,比如網絡請求,這時最好的方式就是在此方法中執(zhí)行,這樣可以避免每次build()都執(zhí)行這些昂貴操作。
重點: 如子控件build 方法中沒有使用 InheritedShareWidget 的數據,那么它的didChangeDependencies將不會被調用
如何使用?
我們簡單用一個 count 自增的例子來記錄 InheritedWidget 的使用:
- 新建 InheritedShareWidget 繼承 InheritedWidget 作為共享數據源,以其為父節(jié)點提供子節(jié)點數據
import 'package:flutter/material.dart';
class InheritedShareWidget extends InheritedWidget {
//用于共享的數據
final int data;
InheritedShareWidget({this.data, Widget child}) : super(child: child);
//定義便捷方法,方便子控件獲取共享數據
static InheritedShareWidget of(BuildContext context) {
///當子控件依賴使用了我們的數據源時,數據變動會觸發(fā)子控件中的 didChangeDependencies 方法
return context.dependOnInheritedWidgetOfExactType<InheritedShareWidget>();
///(前提:子控件使用了數據源)子控件中的 didChangeDependencies 方法不會被觸發(fā)
// return context.getElementForInheritedWidgetOfExactType<InheritedShareWidget>().widget;
}
@override
bool updateShouldNotify(covariant InheritedShareWidget oldWidget) {
//返回true時,才會通知子控件
return oldWidget.data != this.data;
}
}
注意:updateShouldNotify方法中,通知指的是通知子控件的didChangeDependencies 方法,前提是子控件使用dependOnInheritedWidgetOfExactType 的方式獲取共享數據。
- 子節(jié)點中如何獲取共享數據?
class TestShareChildWidget extends StatefulWidget {
const TestShareChildWidget({Key key}) : super(key: key);
@override
_TestShareChildWidgetState createState() => _TestShareChildWidgetState();
}
class _TestShareChildWidgetState extends State<TestShareChildWidget> {
@override
void didChangeDependencies() {
///如build 方法中沒有使用 InheritedShareWidget 的數據,那么它的didChangeDependencies()將不會被調用
super.didChangeDependencies();
print("enter didChangeDependencies");
}
@override
Widget build(BuildContext context) {
print("enter child build");
//獲取Inherited的共享數據:
final data = InheritedShareWidget.of(context).data.toString();
return Text(data);
}
}
- 兩者通過父子嵌套的關系聯(lián)系在一起:
class _TestInheritedWidgetState extends State<TestInheritedWidget> {
int count = 0;
@override
Widget build(BuildContext context) {
return Center(
child: InheritedShareWidget(
data: count,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TestShareChildWidget(),
RaisedButton(
child: Text('add'),
onPressed: () {
setState(() {
++count;
});
})
],
),
),
);
}
}
大家注意到,demo中操作++count時,使用了setState手動觸發(fā)控件進行刷新。
結論
InheritedWidget只提供我們共享數據的能力,以及控制是否在 build 前觸發(fā)didChangeDependencies 的能力。不會主動觸發(fā)build方法,如果build沒被觸發(fā),那么didChangeDependencies 也不會被觸發(fā)。
號外擴展
InheritedWidget 數據共享能力不會受到 Navigator push 新頁面的影響,與原生不一樣,flutter的頁面跳轉不是管理一個堆棧,Navigator 本質上是使用 overlay 管理一個 stack widget,因此 InheritedWidget 基于父子關系管理的數據共享條件沒有被打破
以上就是flutter InheritedWidget使用方法總結的詳細內容,更多關于flutter InheritedWidget使用的資料請關注腳本之家其它相關文章!
相關文章
Android 中StringBuffer 和StringBuilder常用方法
這篇文章主要介紹了Android 中StringBuffer 和StringBuilder的常用方法及區(qū)別介紹,需要的朋友可以參考下2017-02-02
使用RoundedBitmapDrawable生成圓角圖片的方法
由于RoundedBitmapDrawable類沒有直接提供生成圓形圖片的方法,所以生成圓形圖片首先需要對原始圖片進行裁剪,將圖片裁剪成正方形,最后再生成圓形圖片,具體實現方法,可以參考下本文2016-09-09
Android在view.requestFocus(0)返回false的解決辦法
這篇文章主要介紹了Android在view.requestFocus(0)返回false的解決辦法,非常不錯,具有參考借鑒價值,需要的朋友參考下2016-08-08

