Flutter知识点: InheritedWidget

作者: jzhu085 | 来源:发表于2018-06-30 11:27 被阅读143次

    如果你已经开始学习Flutter了,是不是很熟悉这段代码。

    @override
    Widget build(BuildContext context) {
      return new Text(
         'Flutter Demo',
         style: Theme.of(context).textTheme.title,
       );
    }
    

    inherited widget就像对其他的Widget的一个实现或者说是补充,就像Theme.of(context)返回你能拿到一个ThemeData,并使用其内部自定义的属性改变你当前widget的显示效果。

    Theme这个源码大家可以去看一下 ,对理解 InheritedWidget会有比较大的帮助
    如何在不同的widget中获得共同的数据,本文写个简单的计数器来解释:

    inherited_widget.gif

    1.创建一个model,用于保存当前的计数值

    class InheritedTestModel {
      final int count;
      const InheritedTestModel(this.count);
    }
    

    2.创建一个InheritedWidget

    class InheritedContext extends InheritedWidget {
      
      //数据
      final InheritedTestModel inheritedTestModel;
    
      //点击+号的方法
      final Function() increment;
    
      //点击-号的方法
      final Function() reduce;
    
      InheritedContext({
        Key key,
        @required this.inheritedTestModel,
        @required this.increment,
        @required this.reduce,
        @required Widget child,
      }) : super(key: key, child: child);
    
      static InheritedContext of(BuildContext context) {
        return context.inheritFromWidgetOfExactType(InheritedContext);
      }
    
      //是否重建widget就取决于数据是否相同
      @override
      bool updateShouldNotify(InheritedContext oldWidget) {
        return inheritedTestModel != oldWidget.inheritedTestModel;
      }
    }
    

    3.把 "+" ,“-”, "value" 3个widget隔离

    class TestWidgetA extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        final inheritedContext = InheritedContext.of(context);
    
        final inheritedTestModel = inheritedContext.inheritedTestModel;
    
        print('TestWidgetA 中count的值:  ${inheritedTestModel.count}');
        return new Padding(
          padding: const EdgeInsets.only(left: 10.0, top: 10.0, right: 10.0),
          child: new RaisedButton(
              textColor: Colors.black,
              child: new Text('+'),
              onPressed: inheritedContext.increment),
        );
      }
    }
    
    
    class TestWidgetB extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
    
        final inheritedContext = InheritedContext.of(context);
    
        final inheritedTestModel = inheritedContext.inheritedTestModel;
    
        print('TestWidgetB 中count的值:  ${inheritedTestModel.count}');
    
        return  new Padding(
          padding: const EdgeInsets.only(left: 10.0, top: 10.0, right: 10.0),
          child:  new Text('当前count:${inheritedTestModel.count}',style: new TextStyle(fontSize: 20.0),),
        );
      }
    }
    
    
    
    class TestWidgetC extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
    
        final inheritedContext = InheritedContext.of(context);
    
        final inheritedTestModel = inheritedContext.inheritedTestModel;
    
        print('TestWidgetC 中count的值:  ${inheritedTestModel.count}');
    
        return new Padding(
          padding: const EdgeInsets.only(left: 10.0, top: 10.0, right: 10.0),
          child: new RaisedButton(
              textColor: Colors.black,
              child: new Text('-'),
              onPressed: inheritedContext.reduce),
        );
      }
    }
    

    4.组合

    class InheritedWidgetTestContainer extends StatefulWidget {
      @override
      State<StatefulWidget> createState() {
        return new _InheritedWidgetTestContainerState();
      }
    }
    
    class _InheritedWidgetTestContainerState
        extends State<InheritedWidgetTestContainer> {
      InheritedTestModel inheritedTestModel;
    
      _initData() {
        inheritedTestModel = new InheritedTestModel(0);
      }
    
      @override
      void initState() {
        _initData();
        super.initState();
      }
    
      _incrementCount() {
        setState(() {
          inheritedTestModel = new InheritedTestModel(inheritedTestModel.count + 1);
        });
      }
    
      _reduceCount() {
        setState(() {
          inheritedTestModel = new InheritedTestModel(inheritedTestModel.count - 1);
        });
      }
    
      @override
      Widget build(BuildContext context) {
        return new InheritedContext(
            inheritedTestModel: inheritedTestModel,
            increment: _incrementCount,
            reduce: _reduceCount,
            child: new Scaffold(
              appBar: new AppBar(
                title: new Text('InheritedWidgetTest'),
              ),
              body: new Column(
                children: <Widget>[
                  new Padding(
                    padding: const EdgeInsets.only(left: 10.0, top: 10.0, right: 10.0),
                    child: new Text('我们常使用的\nTheme.of(context).textTheme\nMediaQuery.of(context).size等\n就是通过InheritedWidget实现的',
                      style: new TextStyle(fontSize: 20.0),),
                  ),
                  new TestWidgetA(),
                  new TestWidgetB(),
                  new TestWidgetC(),
                ],
              ),
            ));
      }
    }
    
    

    结果:当你操作"+",“-”,中间value会发现变化,A B C 三个widget都能实时获取到当前改变的值

    image.png

    知乎日报Flutter版代码已经上传到我的GITHUB ZhihuDailyPurifyByFlutter

    基础学习过程中的代码都放在GITHUB Flutter_Study

    每天学一点,学到Flutter发布正式版!

    相关文章

      网友评论

      • Passon_Fang:没明白 inherited 优势在哪里,例子中的功能有很多种实现方式
        jzhu085:@Passon_Fang 数据分发,你可以在pub里看下redux和ScopeModel

      本文标题:Flutter知识点: InheritedWidget

      本文链接:https://www.haomeiwen.com/subject/vvzzyftx.html