我不建议将 GlobalKey 用于此任务。
您应该传递数据,而不是小部件,而不是小部件状态。例如,如果您想要在演示中使用Switch 和Slider,最好将实际的boolean 和double 传递到这两个小部件后面。对于更复杂的数据,您应该查看Provider、InheritedWidget 等。
自该视频发布以来,情况发生了变化。 Saed 的回答(我奖励了 50 分)可能是视频中的做法,但它在最近的 Flutter 版本中不再有效。基本上目前没有使用 GlobalKey 轻松实现演示的好方法。
但是……
如果你能保证,两个小部件永远不会同时出现在屏幕上,或者更准确地说,它们永远不会同时插入到同一帧上的小部件树中,那么您可以尝试使用GlobalKey 在布局的不同部分使用相同的小部件。
请注意,这是一个非常严格的限制。例如,当滑动到另一个屏幕时,通常会有一个过渡动画,两个屏幕同时渲染。那不行。所以在这个演示中,我插入了一个“空白页”来防止滑动时出现这种情况。
如何:
因此,如果您想要相同的小部件出现在非常不同的屏幕上(希望它们彼此相距很远),您可以使用 GlobalKey 来做到这一点,基本上只需 3 行代码。
首先,声明一个可以从两个屏幕访问的变量:
final _key = GlobalKey();
然后,在您的小部件中,有一个构造函数,该构造函数接受一个键并将其传递给父类:
Foo(key) : super(key: key);
最后,每当您使用小部件时,将相同的键变量传递给它:
return Container(
color: Colors.green[100],
child: Foo(_key),
);
完整来源:
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(home: MyApp()));
}
class MyApp extends StatelessWidget {
final _key = GlobalKey();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Global Key Demo")),
body: PageView.builder(
itemCount: 3,
itemBuilder: (context, index) {
switch (index) {
case 0:
return Container(
color: Colors.green[100],
child: Foo(_key),
);
break;
case 1:
return Container(
color: Colors.blue[100],
child: Text("Blank Page"),
);
break;
case 2:
return Container(
color: Colors.red[100],
child: Foo(_key),
);
break;
default:
throw "404";
}
},
),
);
}
}
class Foo extends StatefulWidget {
@override
_FooState createState() => _FooState();
Foo(key) : super(key: key);
}
class _FooState extends State<Foo> {
bool _switchValue = false;
double _sliderValue = 0.5;
@override
Widget build(BuildContext context) {
return Column(
children: [
Switch(
value: _switchValue,
onChanged: (v) {
setState(() => _switchValue = v);
},
),
Slider(
value: _sliderValue,
onChanged: (v) {
setState(() => _sliderValue = v);
},
)
],
);
}
}