我们有两种方法在子 widget 树中获取父级 StatefulWidget 的State 对象:
1、通过Context获取
context对象有一个findAncestorStateOfType()方法,该方法可以从当前节点沿着 widget 树向上查找指定类型的 StatefulWidget 对应的 State 对象。比如下面一段例子:
...
return LayoutBuilder(
builder: (context, constraints) {
return Scaffold(
appBar: AppBar(
title: Text("Context测试"),
),
body: Row(
children: [
SizedBox(
width: 100,
height: 30,
),
Expanded(
child: Container(
padding: const EdgeInsets.all(30),
color: Colors.red,
child: Container(
padding: const EdgeInsets.all(3),
color:Theme.of(context).colorScheme.primaryContainer,
child: page,
),
),
),
],
),
);
}
);
...
Widget build(BuildContext context) {
Scaffold? scaffold = context.findAncestorWidgetOfExactType<Scaffold>();
// 直接返回 AppBar的title, 此处实际上是Text("Context测试")
if (scaffold != null && scaffold.appBar != null) {
print((scaffold.appBar as AppBar).title);
}
//Scaffold提供了一个直接通过of静态方法来获取ScaffoldState
ScaffoldState _state=Scaffold.of(context);
// 注意此处找到的是向上离得最近的一个Container
Container? row = context.findAncestorWidgetOfExactType<Container>();
print(row);
}
2、通过GlobalKey
1、给目标StatefulWidget添加GlobalKey
//定义一个globalKey, 由于GlobalKey要保持全局唯一性,我们使用静态变量存储
static GlobalKey<ScaffoldState> _globalKey= GlobalKey();
...
Scaffold(
key: _globalKey , //设置key
...
)
2、通过GlobalKey来获取State对象
_globalKey.currentState
注意:使用 GlobalKey 开销较大,尽量用其他方案。同一个 GlobalKey 在整个 widget 树中必须是唯一的,不能重复(查找资料显示必须唯一,但实际开发中貌似没有出现问题,但尽量避免同名吧)