如何解决带有navigatorKey和key的Flutter MaterialApp无法重新启动
测试时,按几次增量按钮以查看应用程序是否重新启动。
我试图在Flutter中“重启”一个玩具应用程序。我使用的是旧的counter
示例,修改后的行为并非预期。
例如,使用以下代码:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final GlobalKey<NavigatorState> _navigatorKey = GlobalKey<NavigatorState>();
UniqueKey _materialKey;
UniqueKey _homeKey;
@override
void initState() {
super.initState();
_awaitAndRun();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
key: _materialKey,navigatorKey: _navigatorKey,title: 'Flutter Demo',theme: ThemeData(
primarySwatch: Colors.blue,visualDensity: VisualDensity.adaptivePlatformDensity,),home: MyHomePage(
key: _homeKey,title: 'Flutter Demo Home Page',);
}
Future<void> _awaitAndRun() async {
print('Starting delay... Please press the button before the time ends.');
await Future<dynamic>.delayed(Duration(seconds: 5));
setState(() {
_materialKey = UniqueKey();
_homeKey = UniqueKey();
});
print('Has been the screen reloaded?');
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key,this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,children: <Widget>[
Text(
'You have pushed the button this many times:',Text(
'$_counter',style: Theme.of(context).textTheme.headline4,],floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,tooltip: 'Increment',child: Icon(Icons.add),);
}
}
awaitAndRun
函数应重新启动应用程序,因为我将_materialKey
和_homeKey
设置为新实例。作为其一部分,还应该重建MyHomePage
小部件(因为key
值已更改),但是没有。
我可以理解,这是因为_navigatorKey
正在“保存” MaterialApp
的状态,但是MyHomePage
应该重新构建,因为其密钥已更改!
这更加奇怪,因为如果我删除了_materialKey
(如下面的代码所示),则MyHomePage
小部件将被重建。
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final GlobalKey<NavigatorState> _navigatorKey = GlobalKey<NavigatorState>();
UniqueKey _materialKey;
UniqueKey _homeKey;
@override
void initState() {
super.initState();
_awaitAndRun();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
//key: _materialKey,);
}
}
所以对我来说毫无意义,为什么会这样?为什么当我设置_materialKey
时MyHomePage
小部件无法重建?
解决方法
这很正常。 Flutter始终以安全清洁状态为目标,通常不会保留任何物品。您可以使用很多方法,所以我认为provider
您需要将游戏状态保持为应用程序状态,因此我创建了ToysGame(sample)并添加了count属性,您可以使用和更改此属性,以便不受影响的状态发生变化。
首先将单个提供程序实例包装到您的应用页面。
home: Provider(
create: (context) => ToysGame(),child: MyHomePage(
key: _homeKey,title: 'Flutter Demo Home Page',),
在不依靠页面状态继续计数之后,您应该对提供者使用玩具状态。
Text(
Provider.of<ToysGame>(context).count.toString(),style: Theme.of(context).textTheme.headline4,
您想更改值
void _incrementCounter() {
Provider.of<ToysGame>(context,listen: false).count++;
setState(() {});
}
最后,完成了。我在我的stackhelpover存储库中添加了重新启动应用程序库名称。 (您已阅读了提供程序包以及可能为您提供的其他功能帮助[更改通知程序或多提供程序]) StackHelpOver