视频:https://www.youtube.com/watch?v=Zbm3hjPjQMk
可以通过继承InheritedWidget来使得当前widget的变化可被子widget感知;而且子Widget可以直接调用该Widget的某些数据,而如果不用InheritedWidget,就需要在从顶层Widget到底层Widget的所有Widget的构造函数中加上该数据参数。
如:
import 'package:flutter/cupertino.dart'; import "package:flutter/material.dart"; import 'package:flutter/rendering.dart'; import "package:flutter/src/material/dialog.dart"; import 'package:flutter/gestures.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget{ @override Widget build(BuildContext context) { return MaterialApp( title: 'fuck', theme: ThemeData( primarySwatch: Colors.green, ), home: TestPage(), color: Colors.black, ); } } class ParentWidget extends InheritedWidget { //由于extends了InheritedWidget 这个widget的state发生变化时,依赖了该widget状态(内部数据)的子widget // 都会触发didChangeDependencies+build, final int data; ParentWidget({ @required this.data, Widget child }) :super(child:child); static ParentWidget of (BuildContext context) { return context.dependOnInheritedWidgetOfExactType<ParentWidget>(); //这个方法会注册调用Widget和ParentWidget的联系;如果用findAncestorOfExcatType不会注册联系,
//只是沿Widget树向上寻找第一个满足类型条件的Widget } @override bool updateShouldNotify(ParentWidget oldWidget) { return oldWidget.data != data; } }class childOfParentWidget extends StatefulWidget { @override State<StatefulWidget> createState() => childOfParentWidgetState(); } class childOfParentWidgetState extends State<childOfParentWidget> { @override Widget build(BuildContext context) { print('childOfParentWidget进入BUILD了!'); return Text( ParentWidget.of(context).data.toString(), '我不变', style: TextStyle(fontSize: 25),); } @override void didChangeDependencies() { print('childOfParentWidget进入didChangeDependencies了!'); super.didChangeDependencies(); } } class TestPage extends StatefulWidget { @override State<StatefulWidget> createState() => TestPageState(); } class TestPageState extends State<TestPage> { int _data = 0; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text('测试InheritedWidget'), backgroundColor: Colors.green,), body: Center( child: ParentWidget(data: _data, child: Column( children: <Widget>[ childOfParentWidget(), RaisedButton(onPressed: () => setState((){_data++;print('_data=$_data');}),) ], ),), ), ); } }
其中parentWidget继承了InheritedWidget,childOfParentWidget内部引用了parentWidget的_data数据。
所以在parentWidget中的_data改变时,就会触发childParentWidget的didChanDependencies回调。
可以看到:点击按钮后子widget会调用didChangeDependencies,
而如果把child类中的Text设置为一个字符串,取消与parent类中_data的绑定,重新运行点击按钮就不会调用didChangeDependencies了。