flutter InheritedWidget

视频: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了。 

原文地址:https://www.cnblogs.com/FdWzy/p/13497232.html