如需轉載,請注明出處:Flutter學習筆記(27)--資料共享(InheritedWidget)
InheritedWidget是Flutter中非常重要的一個功能型組件,它提供了一種資料在widget樹中從上到下傳遞、共享的方式,比如我們在應用的根widget中通過InheritedWidget共享了一個資料,那么我們便可以在任意子widget中來獲取該共享的資料,
前言:假設有這么一個場景,A、B兩個組件,A組件有一個資料data,當A組件中的這個資料data發生變化后,B組件需要跟隨著做一些處理操作,這時候,如果不通過廣播或其他方式通知B組件,我們有什么辦法實作這個功能呢?
didChangeDependencies
在State物件中,有一個didChangeDependencies回呼,這個回呼會在“依賴”發生變化時被Flutter Framework呼叫,而這個“依賴”指的是子widget是否用到了父widget中的InheritedWidget共享資料,如果使用了,則代表子widget依賴InheritedWidget,反之如果沒有使用則代表沒有依賴,這種機制可以使子組件在所依賴的InheritedWidget發生變化時來更新自身,這也就可以實作我們前面所假設的場景了!
接下來先給大家看一下整體的代碼和效果截圖,心里先有一個大概的概念,帶著幾個概念去思考:1.依賴 2.didChangeDependencies回呼 3.InheritedWidge通過什么來通知子widget
import 'package:flutter/material.dart';void main() => runApp(MyApp());class FatherWidget extends InheritedWidget { final int data; FatherWidget({@required this.data, Widget child}) : super(child: child); //子樹通過該方法獲取共享資料 static FatherWidget getData(BuildContext context) { return context.inheritFromWidgetOfExactType(FatherWidget); } //該回呼決定當data發生變化時,是否通知子樹中依賴data的widget @override bool updateShouldNotify(FatherWidget oldWidget) { return oldWidget.data != data; }}class ChildWidget extends StatefulWidget { @override _ChildWidgetState createState() => _ChildWidgetState();}class _ChildWidgetState extends State<ChildWidget> { @override Widget build(BuildContext context) { return new Text(FatherWidget.getData(context).data.toString()); } @override void didChangeDependencies() { super.didChangeDependencies(); //父或祖先widget中的InheritedWidget改變(updateShouldNotify回傳true)時會被呼叫 //如果build中沒有依賴InheritedWidget,則此回呼不會被呼叫 print("didChangeDependencies = " + FatherWidget.getData(context).data.toString()); }}class MyApp extends StatefulWidget { @override State<StatefulWidget> createState() { return _MyAppState(); }}class _MyAppState extends State<MyApp> { int count = 0; @override Widget build(BuildContext context) { return new MaterialApp( title: 'title', home: new Scaffold( appBar: new AppBar( title: new Text('title'), ), body: new Center( child: FatherWidget( data: count, child: new Column( children: <Widget>[ ChildWidget(), new FloatingActionButton(onPressed: _changeCount,child: new Icon(Icons.adjust),), ], ), ), ), ), ); } _changeCount() { setState(() { ++count; print('mCount == ' + count.toString()); }); }}

整體代碼說明:
點擊按鈕后會呼叫_changeCount()方法,方法內給count數加1,然后通知框架重新build,重新build會給FatherWidget內的data重新賦值,data的資料發生了變化,updateShouldNotify會回傳true,通知子widget執行didChangeDependencies回呼來處理一下回應操作,
分塊說明一下實作資料共享都需要哪幾步:
1.用于存盤共享資料的父Widget,該widget繼承InheritedWidget
class FatherWidget extends InheritedWidget { final int data; FatherWidget({@required this.data, Widget child}) : super(child: child); //子樹通過該方法獲取共享資料 static FatherWidget getData(BuildContext context) { return context.inheritFromWidgetOfExactType(FatherWidget); } //該回呼決定當data發生變化時,是否通知子樹中依賴data的widget @override bool updateShouldNotify(FatherWidget oldWidget) { return oldWidget.data != data; }}
2.子widget,用來處理依賴發生變化時的回應處理操作didChangeDependencies
class ChildWidget extends StatefulWidget { @override _ChildWidgetState createState() => _ChildWidgetState();}class _ChildWidgetState extends State<ChildWidget> { @override Widget build(BuildContext context) { return new Text(FatherWidget.getData(context).data.toString()); } @override void didChangeDependencies() { super.didChangeDependencies(); //父或祖先widget中的InheritedWidget改變(updateShouldNotify回傳true)時會被呼叫 //如果build中沒有依賴InheritedWidget,則此回呼不會被呼叫 print("didChangeDependencies = " + FatherWidget.getData(context).data.toString()); }}
3.FahterWidget和ChildWidget產生依賴關系
//子樹通過該方法獲取共享資料 static FatherWidget getData(BuildContext context) { return context.inheritFromWidgetOfExactType(FatherWidget); }
4.資料更新,通過setState來重新build
class MyApp extends StatefulWidget { @override State<StatefulWidget> createState() { return _MyAppState(); }}class _MyAppState extends State<MyApp> { int count = 0; @override Widget build(BuildContext context) { return new MaterialApp( title: 'title', home: new Scaffold( appBar: new AppBar( title: new Text('title'), ), body: new Center( child: FatherWidget( data: count, child: new Column( children: <Widget>[ ChildWidget(), new FloatingActionButton(onPressed: _changeCount,child: new Icon(Icons.adjust),), ], ), ), ), ), ); } _changeCount() { setState(() { ++count; print('mCount == ' + count.toString()); }); }}
最后需要注意一點,上面說到的依賴前提是兩個組件是父、子的關系,我試了一下,如果FatherWidget中沒有ChildWidget,只是單純的使用了FatherWidget的資料的話,是不會觸發didChangeDependencies回呼的!!!
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/58625.html
標籤:Android
