由於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來獲取! 步驟分兩步:
-
給目標
StatefulWidget
添加GlobalKey
。//定義一個globalKey, 由於GlobalKey要保持全局唯一性,我們使用靜態變量存儲 static GlobalKey<ScaffoldState> _globalKey= GlobalKey(); ... Scaffold( key: _globalKey , //設置key ... )
-
通過
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樹中必須是唯一的,不能重複。