Flutter knows InheritedWidget

1. What is InheritedWidget?

The official said that InheritedWidget is a very important functional widget in flutter. It provides a way to transfer and share data from top to bottom in the widget tree. For example, if we share a piece of data through InheritedWidget in the root widget of the application, then We can get the shared data in any sub-widget! This feature is very convenient in some scenarios where data needs to be shared in the widget tree!

Two, use


class ShareDataWidget extends InheritedWidget{
    
    
 
  int data;
 
  ShareDataWidget({
    
    @required this.data,Widget child}) : super(child: child);
 
  //定义一个方法,方便子树中的widget获取这个widget,进而获得共享数据。
  static ShareDataWidget of(BuildContext context,{
    
    bool rebuild = true}){
    
    
    if(rebuild){
    
    
     
      return context.dependOnInheritedWidgetOfExactType<ShareDataWidget>();
    }
//    return (context.getElementForInheritedWidgetOfExactType<ShareDataWidget>()).widget;
    return context.findAncestorWidgetOfExactType<ShareDataWidget>();
  }
  }
 
  /**
   * framework通过使用以前占据树中的这个位置的小部件作为参数调用这个函数来区分这些情况。
   */
  @override
  bool updateShouldNotify(ShareDataWidget oldWidget) {
    
    
    return oldWidget.data != data;
  }
}

dependOnInheritedWidgetOfExactType:
* Get the nearest Widget of a given type, which must be a subclass of InheritedWidget, *
and register the incoming context with the widget, when the widget changes,
* the context will be rebuilt to get a new one from the widget value.
* This is how child registers with InheritedWidget.

When this method is called, the corresponding child widget will call the didChangeDependencies method.

findAncestorWidgetOfExactType:
The function is the same as dependOnInheritedWidgetOfExactType, but it only looks for subclasses of InheritedWidget, so it can find the superior Widget with O(1) complexity.
When this method is called, the corresponding child widget will not call the didChangeDependencies method.

Why is this so? The reason is that the dependOnInheritedWidgetOfExactType method registers InheritedWidget and its child widgets to register dependencies. And findAncestorWidgetOfExactType does not. If you want to see the details, you can click into the source code of these two methods to see.


class TestWidget extends StatefulWidget{
    
    
  final Widget child;
  TopPage({
    
    this.child});
  @override
  State<StatefulWidget> createState() {
    
    
    return _TestWidgetState();
  }
}

class _TestWidgetState  extends State<TestWidget>{
    
    
  int count=0;

  @override
 @override
  Widget build(BuildContext context) {
    
    
     return Column(
       children: <Widget>[
         ShareDataWidget(
           data: count,
           child: widget.child,
         ),
         RaisedButton( child: Text("Increment"),onPressed: () => setState(() => ++count)),
       ],
     );
  }

}

class ChildAWidget extends StatelessWidget{
    
    
  @override
  Widget build(BuildContext context) {
    
    
    print("ChildAWidget build");
    int test = ShareDataWidget.of(context,rebuild: true).data;
    print(test);
    return Container(child:
       Text(test.toString())
      ,);
  }
}


class ChildBWidget extends StatelessWidget{
    
    
  @override
  Widget build(BuildContext context) {
    
    
    print("ChildBWidget build");
    int test = ShareDataWidget.of(context,rebuild: false).data;
    print(test);
    return Container(child:
    Text("ChildBWidget")
      ,);
  }
}

Widget build(BuildContext context) {
    
    
    return Scaffold(
      body: Padding(
        padding: const EdgeInsets.all(128.0),
        child: Center(child:TestWidget(
      child: Column(
        children: <Widget>[
          ChildAWidget(),
          ChildBWidget(),
        ],
        ),
       )
      ),
    ));

The result of the above operation is as follows, ChildAWidget is built, but ChildBWidget will not be built

I/flutter (18210): ChildAWidget build
I/flutter (18210): 1

You can see that if rebuild is set to true, then it will be rebuild, otherwise it will not.
Therefore, some partial refresh operations can be done as needed, which is very good.

To sum up: If hierarchically nested widgets want to share the same data, they can obtain the shared data by calling ShareDataWidget.of(context).data instead of transferring data layer by layer.

The above are just some superficial studies I have done, welcome to advise! Flowers are over!

Analysis of InheritWidget Source Code of Flutter (https://juejin.cn/post/6943189587061800996)

Guess you like

Origin blog.csdn.net/hjjdehao/article/details/114985547