flutter在Widget樹中獲取State對象

由於StatefulWidget的的具體邏輯都在其State中,所以很多時候,我們需要獲取StatefulWidget對應的State對象來調用一些方法,比如Scaffold組件對應的狀態類ScaffoldState中就定義了打開SnackBar(路由頁底部提示條)的方法。我們有兩種方法在子widget樹中獲取父級StatefulWidget的State對象。

通過Context獲取

context對象有一個ancestorStateOfType(TypeMatcher)方法,該方法可以從當前節點沿着widget樹向上查找指定類型的StatefulWidget對應的State對象。下面是實現打開SnackBar的示例:

Scaffold(
  appBar: AppBar(
    title: Text("子樹中獲取State對象"),
  ),
  body: Center(
    child: Builder(builder: (context) {
      return RaisedButton(
        onPressed: () {
          // 查找父級最近的Scaffold對應的ScaffoldState對象
          ScaffoldState _state = context.ancestorStateOfType(
              TypeMatcher<ScaffoldState>());
          //調用ScaffoldState的showSnackBar來彈出SnackBar
          _state.showSnackBar(
            SnackBar(
              content: Text("我是SnackBar"),
            ),
          );
        },
        child: Text("顯示SnackBar"),
      );
    }),
  ),
);

 

// 直接通過of靜態方法來獲取ScaffoldState 
ScaffoldState _state=Scaffold.of(context); 

通過GlobalKey

Flutter還有一種通用的獲取State對象的方法——通過GlobalKey來獲取! 步驟分兩步:

  1. 給目標StatefulWidget添加GlobalKey

    //定義一個globalKey, 由於GlobalKey要保持全局唯一性,我們使用靜態變量存儲
    static GlobalKey<ScaffoldState> _globalKey= GlobalKey();
    ...
    Scaffold(
        key: _globalKey , //設置key
        ...  
    )
    
  2. 通過GlobalKey來獲取State對象

    _globalKey.currentState.openDrawer()
    

GlobalKey是Flutter提供的一種在整個APP中引用element的機制。如果一個widget設置了GlobalKey,那麼我們便可以通過globalKey.currentWidget獲得該widget對象、globalKey.currentElement來獲得widget對應的element對象,如果當前widget是StatefulWidget,則可以通過globalKey.currentState來獲得該widget對應的state對象。

注意:使用GlobalKey開銷較大,如果有其他可選方案,應儘量避免使用它。另外同一個GlobalKey在整個widget樹中必須是唯一的,不能重複。

 

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