【Flutter】用InheritedWidget来实现全局变量

最近在研究使用Flutter来写一个跨平台的App,之前研究过使用Java来编写Android应用,且对于Java语言也比较熟悉,而Flutter使用Dart语言来编写的,因此在熟悉Dart语言和Flutter框架的过程中也遇到不少问题。

看了很多网上的资料和官方文档,Dart似乎不支持全局变量,而且Flutter将所有的东西抽象为Widget,并将其分为有状态的StatefulWidget和无状态的StatelessWidget,每一个控件中的变量都被抽象成了状态state,有状态的state改变的时候就会刷新控件达到改变的目的,因此问题就转化为了如何定义一个多个控件共享的state,比如Flutter提供的InheritedWidget就可以实现类似全局变量的功能。

 

一、InheritedWidget

InheritedWidget是一个小部件的基类,用于有效地Widget树中传播信息,InheritedWidget的子控件会自动搜寻其祖先节点中离自己最近的InheritedWidget控件,并获取InheritedWidget控件的变量,因此全局变量只需要定义在InheritedWidget中,并用InheritedWidget控件作为需要共享该变量的祖先节点就可以了。

下面看一下官方提供的例子:

class FrogColor extends InheritedWidget {
  const FrogColor({
    Key key,
    @required this.color,
    @required Widget child,
  }) : assert(color != null),
       assert(child != null),
       super(key: key, child: child);

  final Color color;

  static FrogColor of(BuildContext context) {
    return context.inheritFromWidgetOfExactType(FrogColor) as FrogColor;
  }

  @override
  bool updateShouldNotify(FrogColor old) => color != old.color;
}

其中,Color就是共享的变量;

of方法是一个静态方法,该方法调用BuildContext.inheritFromWidgetOfExactType,用来返回FrogColor部件,当然也可以返回数据,比如保存的共享变量Color;

updateShouldNotify方法是该控件的刷新逻辑,上面的方法体中就表示当color的值改变的时候刷新控件。

 

二、共享可变变量

用官方提供的例子由于是用final修饰的,因此子控件不能够改变其值,如果想要创建一个可变得变量,就可以用到我们一开始提到的state,在InheritedWidget中保存一个StatefulWidget,就可以通过这个StatefulWidget来管理要保存的变量了:

class _SharedInherited extends InheritedWidget {
  _SharedInherited({
    Key key,
    @required Widget child,
    @required this.data,
  }) : super(key: key, child: child);

  final SharedInheritedWidgetState data;    //通过一个StatefulWidgetState来保存数据

  @override
  bool updateShouldNotify(_SharedInherited oldWidget) {    //数据更新
    return data != oldWidget.data;
  }
}

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

  final Widget child;

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

  static SharedInheritedWidgetState of(BuildContext context) {
    return (context.inheritFromWidgetOfExactType(_SharedInherited)
    as _SharedInherited)
        .data;
  }
}

class SharedInheritedWidgetState extends State<SharedInheritedWidget> {
  String _sharedVal = '';    //共享变量

  void setSharedVal(String newVal) {
    setState(() {
      _sharedVal = newVal;
    });
  }

  String getSharedVal() {
    return _sharedVal;
  }

  @override
  Widget build(BuildContext context) {
    return _SharedInherited(child: widget.child, data: this);
  }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章