【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);
  }
}

 

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