Before we start introducing the inheritedWidget, here’s a bit of knowledge to set the stage for what’s coming

First introduce ancestorWidgetOfExactType

1. Take a look at the Demo code structure

Demo address: github.com/LZQL/flutte…

It’s the most complete demo on the web so far

2. ancestorWidgetOfExactType

Returns the most recent parent widget of the given type, whose type must be a subclass of the specific widget.

In general, the more useful inheritFromWidgetOfExactType because inheritance widget will be triggered when changes consumers rebuild. AncestorWidgetOfExactType suitable for interactive event handler (e.g., gestures callback) or to perform a one-time task, such as assertions you have or do not possess as a specific type of the parent widget. The return value of the widget’s build method should not depend on the value returned by the method, because if the return value of the method changes, the build context will not be regenerated. This may cause the data used in the build method to change, but the widget is not rebuilt.

To summarize the above:

  1. ancestorWidgetOfExactTypeGenerally used to assert whether there is a particular type of parentwidget
  2. ancestorWidgetOfExactTypeCan be used to get the parentwidgetSome information about
  3. If you want to determine whether to rebuild based on the return value of a method,ancestorWidgetOfExactTypeDo not apply

The three points above are summarized below to illustrate the demo scenario

1. The assertion

This side will not give their own demo, directly look at the source code, the source code application scenario explains everything, here is the best proof of the official translation

Hero

2. Access to the fatherwidgetSome information about

1. Code structure

2. Operation effect

WidgeC is a plus button, click WidgeC, get HomepageState call incrementCounter method, widgetA, widgetB, widgetC will rebuild, see the image below

3. Specific code

The code location ancestor01.dart

/ / / ancestorWidgetOfExactType get some information of the parent widget
class MyAncestorTree01 extends StatefulWidget {
  @override
  _MyAncestorTree01State createState() => _MyAncestorTree01State();
}

class _MyAncestorTree01State extends State<MyAncestorTree01> {
  @override
  Widget build(BuildContext context) {
    returnTopPage01(); }}class TopPage01 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        appBar: AppBar(
          title: Text('Demo'), ), body: HomePage(), ), ); }}class HomePage extends StatefulWidget {
  final HomePageState state = HomePageState();

  @override
  HomePageState createState() {
    returnstate; }}class HomePageState extends State<HomePage> {
  int counter = 0;

  void incrementCounter() {

    setState(() {
      counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    returnScaffold( body: Column( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ WidgetA(), WidgetB(), WidgetC(), ], ), ); }}class WidgetA extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    /// Get HomePageState to get counter
    final HomePage widget =
        context.ancestorWidgetOfExactType(HomePage);
    finalHomePageState state = widget? .state;return Center(
      child: Text(
        '${state == null ? 0 : state.counter}', style: Theme.of(context).textTheme.display1, ), ); }}class WidgetB extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Text('Widget B Text'); }}class WidgetC extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    /// Get HomePageState to call the addition operation
    final HomePage widget = context.ancestorWidgetOfExactType(HomePage);
    finalHomePageState state = widget? .state;return RaisedButton(
      onPressed: () {
        state?.incrementCounter();
      },
      child: Icon(Icons.add),
    );
  }
}
Copy the code

3. The child widget cannot detect changes to the parent widget

This demo is used to demonstrate the child widgets can’t detect the specific situation of the changes of the parent widget For the back of the content I will ancestorWidgetOfExactType encapsulates one of method on the TopPage02 inside, and 2. There are different usage scenarios for getting some information about the parent widget.

1. Code structure

2. Operation effect

Look at the picture below, when I click on the 1 – AncestorWidgetOfExactType02 demo button, enter the demo page, can be seen from the right side, because is the first time, so for all the widgets build operation, but when I click on the Add item button, TopPage02 will rebuild, but WidgetA, WidgetB, WidgetC will not rebuild

3. Specific code

The code location ancestor02.dart

/// ancestorWidgetOfExactType
/// The child widget cannot detect changes to the parent widget
/// (parent widget rebuild child widget no rebuild)
class MyAncestorTree02 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new TopPage02(
      child: new Scaffold(
        appBar: new AppBar(
          title: new Text('Title'),
        ),
        body: new Column(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          children: <Widget>[
            new WidgetA(),
            new WidgetB(),
            newWidgetC(), ], ), ), ); }}class Item {
  String reference;

  Item(this.reference);
}

class TopPage02 extends StatefulWidget {
  TopPage02({
    Key key,
    this.child,
  }) : super(key: key);

  final Widget child;

  final TopPage02State state = new TopPage02State();

  @override
  TopPage02State createState() {
    return state;
  }

  static TopPage02State of(BuildContext context) {
    // return the first TopPage02State by retrieving the tree structure from TopPage02 context
    return (context.ancestorWidgetOfExactType(TopPage02)
            asTopPage02) .state; }}class TopPage02State extends State<TopPage02> {

  List<Item> _items = <Item>[];

  int get itemsCount => _items.length;

  void addItem(String reference) {
    setState(() {
      _items.add(new Item(reference));
    });
  }

  @override
  Widget build(BuildContext context) {
    returnwidget.child; }}class WidgetA extends StatefulWidget {
  @override
  _WidgetAState createState() => _WidgetAState();
}

class _WidgetAState extends State<WidgetA> {
  @override
  Widget build(BuildContext context) {
    final TopPage02State state = TopPage02.of(context);
    return new Center(
      child: new RaisedButton(
        child: new Text('WidgetA :Add Item'),
        onPressed: () {
          /// call the addItem method, but WidgetA, WidgetB, WidgetC
          /// do not build
          The return value of a widget's build method should not depend on the value returned by the method.
          /// Because if the return value of this method changes, the build context will not be regenerated.
          /// This may cause the data used in the build method to change, but the widget is not rebuilt
          state.addItem('new item'); },),); }}class WidgetB extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final TopPage02State state = TopPage02.of(context);
    return new Text('widgetB itemCount:${state.itemsCount}'); }}class WidgetC extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Text('I am Widget C'); }}Copy the code

3. InheritedWidget

1. What is InheritedWidget

Features:

  1. InheritedWidgetIs one that can be in a treeEfficiently pass down dataComponent: we can in theInheritedWidgetIs any of the nodes in the treeWidgetIn the callBuildContext.inheritFromWidgetOfExactTypeTo get the nearest oneInheritedWidgetThe instance
  2. When called in the manner aboveinheritFromWidgetOfExactTypeMethod when) is referenced after wheneverInheritedWidgetWhen its state changes, it causes"Consumer"(callinheritFromWidgetOfExactTypeThis one of the methodsChild) tobuild

The InheritedWidget is used to share the Theme and Locale information in Flutter. Solved the above mentioned ancestorWidgetOfExactType third cannot build again through the return value

InheritedWidget transfers data from top to bottom in the Widget tree, which is the opposite of the transfer direction for Notification. (Notification will be introduced in the next series of articles)

2. didChangeDependencies

The State object of the StatefulWidget has a callback to didChangeDependencies, which is called by the Flutter Framework when the “dependency” changes. The “dependency” refers to whether the InheritedWidget’s data is used in the parent widget. If yes, there is a dependency, and if no, there is no dependency. This mechanism gives a child component the opportunity to do something when the dependent topic, locale, and so on changes.

Through 4.2 - InheritedWidget Demo 01, find the problem

This example is a reference book. Flutterchina. Club/chapter7 / in… Written the same, I believe many people have seen

1. Code structure

2. The rendering

When I click the Click Me button plus 1, widgetA, widgeB,RaisedButton will rebuild

3. Code

Inheritedwidget01.dart Code location: InheritedWidget01.dart

/// InheritedWidget01 causes`widgetA`.` widgeB`.`RaisedButton `Will return`build`
  class InheritedWidgetTest01 extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    returnInheritedWidgetTest01State(); }}class InheritedWidgetTest01State extends State<InheritedWidgetTest01> {
  int tmpData = 0;

  @override
  Widget build(BuildContext context) {
    print('InheritedWidgetTest01 build');
    return Scaffold(
      body: Center(
        child: ShareInherited(
          data: tmpData,
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              WidgetA(),
              WidgetB(),
              RaisedButton(
                child: Text("Click me"),
                onPressed: () {
                  setState(() {
                    print('onPressed');
                    tmpData += 1; }); }, [, [, (), (), (), (); }}class ShareInherited extends InheritedWidget {
  final int data; // The number of clicks that need to be shared in the subtree

  ShareInherited({@required this.data, @required Widget child}) : super(child: child) {
    print('ShareInherited construct');
  }

  /// Allow all child widgets to obtain the latest ShareInherited instance through the contained context
  // define a convenient method for widgets in a subtree to get shared data
  /// Internally, in addition to simply returning the ShareInherited real exception, it subscribes to the consumer widget for notification of changes
  static ShareInherited of(BuildContext context) {
    return context.inheritFromWidgetOfExactType(ShareInherited);
  }

  /// is used to tell the InheritedWidget that if the data is modified,
  /// Whether notifications must be passed to all child widgets (registered/subscribed)
  @override
  bool updateShouldNotify(ShareInherited oldWidget) {
    // If true is returned, the widget is dependent on the subtree (called in the build function)
    / / the child widgets ` state. DidChangeDependencies ` will be invoked
    boolresult = oldWidget.data ! =this.data;
    print('ShareInherited updateShouldNotify result = $result');
    returnresult; }}class WidgetA extends StatefulWidget {
  @override
  _WidgetAState createState() => _WidgetAState();
}

class _WidgetAState extends State<WidgetA> {
  @override
  Widget build(BuildContext context) {
    print('WidgetA build');
    int data = ShareInherited.of(context).data;
    return Text('WidgetA data = $data');
  }

  @override
  void didChangeDependencies() {
    print('WidgetA didChangeDependencies');
    super.didChangeDependencies(); }}class WidgetB extends StatefulWidget {
  @override
  _WidgetBState createState() => _WidgetBState();
}

class _WidgetBState extends State<WidgetB> {
  @override
  Widget build(BuildContext context) {
    print('WidgetB build');
    return Text('WidgetB');
  }

  @override
  void didChangeDependencies() {
    print('WidgetB didChangeDependencies');
    super.didChangeDependencies(); }}Copy the code

4. Discovered phenomena

WidgetA call inheritFromWidgetOfExactType method, we obtain the data stored in the object ShareInherited data and display on the WidgetA content, while making WidgetA associated with ShareInherited produce;

InheritedWidgetTest01State when click RaisedButton trigger InheritedWidgetTest01 status update the build method of correction, to build ShareInherited object into a new value, When the data changes, the ShareInherited method updateShouldNotify returns true, which causes the ShareInherited associated WidgetA to trigger reBuild.

When we run and click RaisedButton, the page behaves exactly as shown above, with WidgetA’s content changing from WidgetA data = 0 to WidgetA data = 1, which seems to be the right way to use the InheritedWidget. But the output in log is as follows:

I/flutter (11303): onPressed
I/flutter (11303): InheritedWidgetTest01 build
I/flutter (11303): ShareInherited construct
I/flutter (11303): ShareInherited updateShouldNotify result = true
I/flutter (11303): WidgetA didChangeDependencies
I/flutter (11303): WidgetA build
I/flutter (11303): WidgetB build
Copy the code

I/ build (11303): WidgetB build Why is that?

5. Cause analysis

The answer can actually be found in the aforementioned property 2. When the InheriteWidget state changes, the associated child is rebuilt. We know that the widgets in flutter are marked @immutable, so the so-called state change means that the InheriteWidget is reconstructed. Because the child object is also constructed when the InheriteWidget is constructed in the preceding code, Therefore, when the InheriteWidget is rebuilt, the child will also be rebuilt, thus losing the meaning of “rebuild-related child”.

That is, for feature 2 to take effect, the tree under the InheriteWidget node needs to be guaranteed not to be rebuilt.

5. Solution 1: Use const Widget

The child of the InheriteWidget is converted to const, so that even when the InheriteWidget is rebuilt, because its child gets the same object, it does not cause the subtree to be rebuilt, and the selective reBuild is guaranteed. However, because of the const nature, the related parameters must also be constants, so there is a relatively large amount of code that needs to be rewritten or modified, so solution 2, which is written back later, is recommended

1. Const demo 01, found a problem

1. Code structure

2. The rendering

WidgeA, WidgeB and FlatButton are in the same league

When I click click me, widgetB will not be rebuilt, but WidgeA and FlatButton will be rebuilt. But FlateButton doesn’t involve refreshing the page’s data. What if I want FlatButton to also not rebuild? See the demo02 const

3. Code

[inheritedWidget_CONST_01.dart

/ / / use the const
/// Widget A, FlatButton rebuild, Widget B no rebuild
class InheritedWidgetConst01 extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    returnInheritedWidgetConst01State(); }}class InheritedWidgetConst01State extends State<InheritedWidgetConst01> {
  int tmpData = 0;



  @override
  Widget build(BuildContext context) {
    print('InheritedWidgetTest02 build');
    return Scaffold(
      body: Center(
        child: ShareInherited(
          data: tmpData,
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              const WidgetA(),
              const WidgetB(),
              FlatButton(
                child: Text("Click me"),
                onPressed: () {
                  setState(() {
                    print('onPressed');
                    tmpData += 1; }); }, [, [, (), (), (), (); }}class ShareInherited extends InheritedWidget {
  final int data;

  ShareInherited({this.data, @required Widget child}) : super(child: child) {
    print('ShareInherited construct');
  }

  @override
  bool updateShouldNotify(ShareInherited oldWidget) {
    boolresult = oldWidget.data ! =this.data;
    print('ShareInherited updateShouldNotify result = $result');
    return result;
  }

  static ShareInherited of(BuildContext context) {
    returncontext.inheritFromWidgetOfExactType(ShareInherited); }}class WidgetA extends StatelessWidget {

  const WidgetA();

  @override
  Widget build(BuildContext context) {
    print('WidgetA build');
    int data = ShareInherited.of(context).data;
    return Text('WidgetA data = $data'); }}class WidgetB extends StatelessWidget {

  const WidgetB();

  @override
  Widget build(BuildContext context) {
    print('WidgetB build');
    return Text('WidgetB'); }}Copy the code

2. Continue to find problems with const Demo 02

1. Code structure

2. The rendering

You will find that WidgeA and WidgeC or rebuild, to solve this problem, you need to use the article mentioned at the top of the ancestorWidgetOfExactType, see const demo 03, the ultimate way

3. Code

The code location inheritedWidget_CONST_02.dart

/ / / use the const
/// Widget A ,Widget C rebuild, Widget B no rebuild
class InheritedWidgetConst02 extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    returnInheritedWidgetConst02State(); }}class InheritedWidgetConst02State extends State<InheritedWidgetConst02> {
  int tmpData = 0;

  void addItem(){
    setState(() {
      tmpData++;
    });
  }

  @override
  Widget build(BuildContext context) {
    print('InheritedWidgetTest02 build');
    return Scaffold(
      body: Center(
        child: ShareInherited(
          data: tmpData,
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              const WidgetA(),
              const WidgetB(),
              WidgetC(),
            ],
          ),
          state: this,),),); }}class ShareInherited extends InheritedWidget {
  final int data;
  final InheritedWidgetConst02State state;
  ShareInherited({this.data, @required Widget child,this.state}) : super(child: child) {
    print('ShareInherited construct');
  }

  @override
  bool updateShouldNotify(ShareInherited oldWidget) {
    boolresult = oldWidget.data ! =this.data;
    print('ShareInherited updateShouldNotify result = $result');
    return result;
  }

  static ShareInherited of(BuildContext context) {
    returncontext.inheritFromWidgetOfExactType(ShareInherited); }}class WidgetA extends StatelessWidget {

  const WidgetA();

  @override
  Widget build(BuildContext context) {
    print('WidgetA build');
    int data = ShareInherited.of(context).data;
    return Text('WidgetA data = $data'); }}class WidgetB extends StatelessWidget {

  const WidgetB();

  @override
  Widget build(BuildContext context) {
    print('WidgetB build');
    return Text('WidgetB'); }}class WidgetC extends StatefulWidget {
  @override
  _WidgetCState createState() => _WidgetCState();
}

class _WidgetCState extends State<WidgetC> {
  @override
  Widget build(BuildContext context) {
    print('Widge C build');
    InheritedWidgetConst02State state = ShareInherited.of(context).state;

    return FlatButton(
      child: Text("Click me"),
      onPressed: () {
        setState(() {
          print('onPressed'); state.addItem(); }); }); }}Copy the code

3. Const Demo 03, ultimate

1. Code structure

2. The rendering

When I add the rebuild to the ShareInherited of method, you’ll notice that WidgeA is the only one that builds, perfect

  static ShareInherited of([BuildContext context, bool rebuild = true]) {
    return (rebuild
        ? context.inheritFromWidgetOfExactType(ShareInherited)
        : context.ancestorWidgetOfExactType(ShareInherited) );
  }
Copy the code

3. Code

The code location inheritedWidgeT_CONST_03.dart

/ / / use the const
/// Widget A rebuild, Widget B Widget C no rebuild
class InheritedWidgetConst03 extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    returnInheritedWidgetConst03State(); }}class InheritedWidgetConst03State extends State<InheritedWidgetConst03> {
  int tmpData = 0;

  void addItem() {
    setState(() {
      tmpData++;
    });
  }

  @override
  Widget build(BuildContext context) {
    print('InheritedWidgetTest02 build');
    return Scaffold(
      body: Center(
        child: ShareInherited(
          data: tmpData,
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              const WidgetA(),
              const WidgetB(),
              const WidgetC(),
            ],
          ),
          state: this,),),); }}class ShareInherited extends InheritedWidget {
  final int data;
  final InheritedWidgetConst03State state;

  ShareInherited({this.data, @required Widget child, this.state})
      : super(child: child) {
    print('ShareInherited construct');
  }

  @override
  bool updateShouldNotify(ShareInherited oldWidget) {
    boolresult = oldWidget.data ! =this.data;
    print('ShareInherited updateShouldNotify result = $result');
    return result;
  }

  static ShareInherited of([BuildContext context, bool rebuild = true]) {
    return(rebuild ? context.inheritFromWidgetOfExactType(ShareInherited) : context.ancestorWidgetOfExactType(ShareInherited) ); }}class WidgetA extends StatelessWidget {

  const WidgetA();

  @override
  Widget build(BuildContext context) {
    print('WidgetA build');
    int data = ShareInherited
        .of(context)
        .data;
    return Text('WidgetA data = $data'); }}class WidgetB extends StatelessWidget {

  const WidgetB();

  @override
  Widget build(BuildContext context) {
    print('WidgetB build');
    return Text('WidgetB'); }}class WidgetC extends StatelessWidget {
  const WidgetC();
  @override
  Widget build(BuildContext context) {
    print('Widge C build');
    InheritedWidgetConst03State state = ShareInherited.of(context,false).state;

    return FlatButton(
      child: Text("Click me"),
      onPressed: () {
        print('onPressed'); state.addItem(); }); }}Copy the code

6. Solution 2: Move upChildObject toInheriteWidgettheParent Widget

1. Out Demo 01, discover the problem

1. Code structure

2. The rendering

Look at the code, it’s a little complicated, the name here is not very standard, I don’t want to change, too tired to write demo, you can see the code

class ShareInherited extends StatelessWidget
Copy the code

The ShareInherited is a StatelessWidget, which is the Parent Widget that moves the Child object up to the InheriteWidget

class _ShareInherited extends InheritedWidget
Copy the code

And _ShareInherited is the concrete InheritedWidget

The following figure shows that Widget A, FlatButton Rebuild, and Widget B no rebuild

We will put the FlatButton in WidgetC and then move it up to the Parent Widget of the InheriteWidget to see if we can implement WidgeC no rebuild

3. Code

The code location inheritedWidgeT_out_01.dart

/ / / up`Child`Object to`InheriteWidget`the`Parent Widget`
/// Widget A, FlatButton rebuild, Widget B no rebuild
class InheritedWidgetOut01 extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    returnInheritedWidgetOut01State(); }}class InheritedWidgetOut01State extends State<InheritedWidgetOut01> {
  @override
  Widget build(BuildContext context) {

    returnScaffold( body: MyWidget( Column( children: <Widget>[ WidgetA(), WidgetB() ], ) ), ); }}class MyWidget extends StatefulWidget {

  final Widget child;
  MyWidget(this.child);

  @override
  _MyWidgetState createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> {

  int tempData = 0;

  @override
  Widget build(BuildContext context) {
    return ShareInherited(
      data: tempData,
      child: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            widget.child,
            FlatButton(
                  child: Text("Click me"),
                  onPressed: () {
                    setState(() {
                      print('onPressed');
                      tempData += 1; }); },)],),),); }}class ShareInherited extends StatelessWidget {
  final int data;
  final Widget child;


  ShareInherited({
    Key key,
    this.data,
    this.child
  }): assert(child ! =null),
        assert(data ! =null),
        super(key: key);

  static int of(BuildContext context) {
    final _ShareInherited inheritedTheme = context.inheritFromWidgetOfExactType(_ShareInherited);
    return inheritedTheme.shareInherited.data;
  }

  @override
  Widget build(BuildContext context) {
    return _ShareInherited(shareInherited:this, child: child,); }}class _ShareInherited extends InheritedWidget{

  final ShareInherited shareInherited;

  _ShareInherited({
    Key key,
    @required this.shareInherited,
    @required Widget child,
  }):assert(shareInherited ! =null),
  super(key: key, child: child);

  @override
  bool updateShouldNotify(_ShareInherited oldWidget) {
    return shareInherited.data != oldWidget.shareInherited.data;
  }

}

class WidgetA extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    print('WidgetA build');
    int data = ShareInherited.of(context);
    return Text('WidgetA data = $data'); }}class WidgetB extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    print('WidgetB build');
    return Text('WidgetB'); }}Copy the code

2. Out Demo 02, continue to discover problems

1. Code structure

2. The rendering

You will find Widget A,Widget C rebuild, and Widget B no rebuild

If you want Widge C to have no rebuild, see out Demo 03

3. Code

The inheritedWidgeT_out_02.dart code location

/ / / up`Child`Object to`InheriteWidget`the`Parent Widget`
/// Widget A ,Widget C rebuild, Widget B no rebuild
class InheritedWidgetOut02 extends StatefulWidget {
  @override
  _InheritedWidgetOut02State createState() => new _InheritedWidgetOut02State();
}

class _InheritedWidgetOut02State extends State<InheritedWidgetOut02> {
  @override
  Widget build(BuildContext context) {
    return new MyInheritedWidget(
      child: new Scaffold(
        appBar: new AppBar(
          title: new Text('Title'),
        ),
        body: Center(
          child: new Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[new WidgetA(), new WidgetB(), newWidgetC()], ), ), ), ); }}class MyInheritedWidget extends StatefulWidget {
  MyInheritedWidget({
    Key key,
    this.child,
  }) : super(key: key);

  final Widget child;

  @override
  MyInheritedWidgetState createState() => new MyInheritedWidgetState();

  static MyInheritedWidgetState of([BuildContext context]) {
    return (context.inheritFromWidgetOfExactType(_MyInherited) as _MyInherited).data;
    // Return the first MyInheritedWidgetState by getting the tree structure from the MyInheritedWidget's context}}class MyInheritedWidgetState extends State<MyInheritedWidget> {

  int tempData = 0;

  /// Helper method to add an Item
  void addItem() {
    setState(() {
      tempData++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return new _MyInherited(
      data: this, child: widget.child, ); }}class _MyInherited extends InheritedWidget {
  _MyInherited({
    Key key,
    @required Widget child,
    @required this.data,
  }) : super(key: key, child: child);

  final MyInheritedWidgetState data;

  @override
  bool updateShouldNotify(_MyInherited oldWidget) {
    return true; }}class WidgetA extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    print('Widget A build');
    final MyInheritedWidgetState state = MyInheritedWidget.of(context);
    return Text('WidgetA data = ${state.tempData}'); }}class WidgetB extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    print('Widget B build');
    return Text('WidgetB'); }}class WidgetC extends StatefulWidget {
  @override
  _WidgetCState createState() => _WidgetCState();
}

class _WidgetCState extends State<WidgetC> {
  @override
  Widget build(BuildContext context) {
    print('Widget C build');
    final MyInheritedWidgetState state = MyInheritedWidget.of(context);
    return RaisedButton(
      child: Text("Click me"),
      onPressed: () {
        print('onPressed'); state.addItem(); }); }}Copy the code

3. Out Demo 03

1. Code structure

2. The rendering

Because the Perfomance interface display of this demo is not good enough, I will directly display the output log to check the result

Widget A rebuild, Widget B, Widget C no rebuild

3. Code

The inheritedWidgeT_out_03.dart code location

/ / / up`Child`Object to`InheriteWidget`the`Parent Widget`
/// Widget A rebuild, Widget B Widget C no rebuild
class InheritedWidgetOut03 extends StatefulWidget {
  @override
  _InheritedWidgetOut03State createState() => new _InheritedWidgetOut03State();
}

class _InheritedWidgetOut03State extends State<InheritedWidgetOut03> {
  @override
  Widget build(BuildContext context) {
    return new MyInheritedWidget(
      child: new Scaffold(
        appBar: new AppBar(
          title: new Text('Title'),
        ),
        body: Center(
          child: new Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[new WidgetA(), new WidgetB(), newWidgetC()], ), ), ), ); }}class MyInheritedWidget extends StatefulWidget {
  MyInheritedWidget({
    Key key,
    this.child,
  }) : super(key: key);

  final Widget child;

  @override
  MyInheritedWidgetState createState() => new MyInheritedWidgetState();

  static MyInheritedWidgetState of(
      [BuildContext context, bool rebuild = true]) {
    return (rebuild
            ? context.inheritFromWidgetOfExactType(_MyInherited) as _MyInherited
            : context.ancestorWidgetOfExactType(_MyInherited) as _MyInherited)
        .data;
    // Return the first MyInheritedWidgetState by getting the tree structure from the MyInheritedWidget's context}}class MyInheritedWidgetState extends State<MyInheritedWidget> {

  int tempData = 0;

  /// Helper method to add an Item
  void addItem() {
    setState(() {
      tempData++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return new _MyInherited(
      data: this, child: widget.child, ); }}class _MyInherited extends InheritedWidget {
  _MyInherited({
    Key key,
    @required Widget child,
    @required this.data,
  }) : super(key: key, child: child);

  final MyInheritedWidgetState data;

  @override
  bool updateShouldNotify(_MyInherited oldWidget) {
    return true; }}class WidgetA extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    print('Widget A build');
    final MyInheritedWidgetState state = MyInheritedWidget.of(context);
    return Text('WidgetA data = ${state.tempData}'); }}class WidgetB extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    print('Widget B build');
    return Text('WidgetB'); }}class WidgetC extends StatefulWidget {
  @override
  _WidgetCState createState() => _WidgetCState();
}

class _WidgetCState extends State<WidgetC> {
  @override
  Widget build(BuildContext context) {
    print('Widget C build');
    final MyInheritedWidgetState state = MyInheritedWidget.of(context, false);
    return RaisedButton(
      child: Text("Click me"),
      onPressed: () {
        print('onPressed'); state.addItem(); }); }}Copy the code

7. Two solutions, application in the source code

Method 1: Look at the TickerMode class

Method 2: You can look at the Theme class

8. Refer to the article

Book. Flutterchina. Club/chapter7 / in…

Qiita.com/ko2ic/items…

Juejin. Cn/post / 684490…

Linjiang. Tech / 2019/02/25 /…

Scan and follow my wechat official account

These are personal study notes

Click below to read the original text, use the computer to see, there is a table of contents, more comfortable oh