Flutter中的InheritedWidget

                                                           Flutter中的InheritedWidget

1.InheritedWidget是什么?

InheritedWidget是Flutter中非常重要的一个功能型组件,它提供了一种数据在widget树中从上到下传递、共享的方式,比如我们在应用的根widget中通过InheritedWidget共享了一个数据,那么我们便可以在任意子widget中来获取该共享的数据!这个特性在一些需要在widget树中共享数据的场景中非常方便!如Flutter SDK中正是通过InheritedWidget来共享应用主题(Theme)和Locale (当前语言环境)信息的。

InheritedWidget和React中的context功能类似,和逐级传递数据相比,它们能实现组件跨级传递数据。InheritedWidget的在widget树中数据传递方向是从上到下的,这和通知Notification(将在下一章中介绍)的传递方向正好相反。

2.如何使用InheritedWidget

1)、创建一个类继承自Inheritedwidget

class InheritedContext extends InheritedWidget{  final InheritedTestModel inheritedTestModel;  InheritedContext({    Key key,    @required this.inheritedTestModel,    @required Widget child}): super(key: key, child: child);static InheritedContext of(BuildContext context) {    return context.dependOnInheritedWidgetOfExactType<InheritedContext>();  }  @override  bool updateShouldNotify(InheritedContext oldWidget) {    return inheritedTestModel != oldWidget.inheritedTestModel;  }}

2)、InheritedTestModel类为数据容器(这里定义了一个List<int>数据源)

class InheritedTestModel{ final List _list;  InheritedTestModel(this._list);  List getList(){    return _list;  }}


class ArrayListData{  static List _list;static List getListData(){    _list = new List();    _list.add(1);    _list.add(2);    _list.add(3);    _list.add(4);return _list;  }}class InheritedContext extends InheritedWidget{  final InheritedTestModel inheritedTestModel;  InheritedContext({    Key key,    @required this.inheritedTestModel,    @required Widget child}): super(key: key, child: child);static InheritedContext of(BuildContext context) {    return context.dependOnInheritedWidgetOfExactType<InheritedContext>();  }  @override  bool updateShouldNotify(InheritedContext oldWidget) {    return inheritedTestModel != oldWidget.inheritedTestModel;  }}

2)、InheritedTestModel类为数据容器(这里定义了一个List<int>数据源)

class InheritedTestModel{ final List _list;  InheritedTestModel(this._list);  List getList(){    return _list;  }}


class ArrayListData{  static List _list;static List getListData(){    _list = new List();    _list.add(1);    _list.add(2);    _list.add(3);    _list.add(4);return _list;  }}class InheritedContext extends InheritedWidget{  final InheritedTestModel inheritedTestModel;  InheritedContext({    Key key,    @required this.inheritedTestModel,    @required Widget child}): super(key: key, child: child);static InheritedContext of(BuildContext context) {    return context.dependOnInheritedWidgetOfExactType<InheritedContext>();  }  @override  bool updateShouldNotify(InheritedContext oldWidget) {    return inheritedTestModel != oldWidget.inheritedTestModel;  }}

2)、InheritedTestModel类为数据容器(这里定义了一个List<int>数据源)

class InheritedTestModel{ final List _list;  InheritedTestModel(this._list);  List getList(){    return _list;  }}


class ArrayListData{  static List _list;static List getListData(){    _list = new List();    _list.add(1);    _list.add(2);    _list.add(3);    _list.add(4);return _list;  }}

2)、InheritedTestModel类为数据容器(这里定义了一个List<int>数据源)

class InheritedTestModel{ final List _list;  InheritedTestModel(this._list);  List getList(){    return _list;  }}


class ArrayListData{  static List _list;static List getListData(){    _list = new List();    _list.add(1);    _list.add(2);    _list.add(3);    _list.add(4);return _list;  }}

3)、定义一个Widget 使用 InheritedContext类的数据 InheritedTestModel 

class ListDemo extends StatefulWidget{  @override  State createState() {    return new ListDemoState();  }}class ListDemoState extends State<ListDemo>{List _list;  InheritedTestModel _inheritedTestModel;  Timer _timer;  Duration oneSec = const Duration(seconds: 1);  @override  void initState() {    _list = ArrayListData.getListData();    _inheritedTestModel = new InheritedTestModel(_list);    _timer = Timer.periodic(oneSec, (timer) {      _doTimer();    });  }  void _doTimer() {    for(int i = 0; i < _list.length; i++){      _list[i] = _list[i]+ 1;    }  setState(() {    _inheritedTestModel = new InheritedTestModel(_list);  });  }Widget _buildBody() {    return Container(child: ListDemo2(),    );  }  @override  Widget build(BuildContext context) {    return InheritedContext(inheritedTestModel: _inheritedTestModel,      child: Scaffold(appBar: AppBar(title: Text("ListDemo"),        actions: <Widget>[            IconButton(icon: Icon(Icons.add),            )        ],),        body: _buildBody(),      ),    );  }  @override  void dispose() {    super.dispose();if (_timer != null) {      _timer.cancel();    }  }}

4)、在ListDemo中通过Timer更新InheritedTestModel 中的数据,然后再下一个Widget中获取更新的数据作为展示

class ListDemo2 extends StatefulWidget{  @override  State createState() {    return new ListDemoState2();  }}class ListDemoState2 extends State<ListDemo2>{InheritedTestModel _inheritedTestModel;  Widget _buildListItem(BuildContext context,int index) {    return  Container(height: 50,        width: 100,        alignment: Alignment.center,        child: Text(_inheritedTestModel.getList()[index].toString()),    );  }Widget _buildBody() {    _inheritedTestModel = InheritedContext.of(context).inheritedTestModel;return Container(child: ListView.builder(itemBuilder:(context, index)=>_buildListItem(context,index),itemCount: _inheritedTestModel.getList().length,),    );  }  @override  Widget build(BuildContext context) {    return  _buildBody();  }}


这样就可以在父widget中更新数据,子View不需任何操作直接从数据容器InheritedTestModel 中获取到更新后的新数据

这是一个数据共享的简单的例子

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容