当弹出时强制Flutter导航器重新加载状态
当弹出时强制Flutter导航器重新加载状态
我在Flutter中有一个带有按钮的StatefulWidget
,使用Navigator.push()
将我导航到另一个StatefulWidget
。在第二个小部件中,我更改了全局状态(一些用户首选项)。当我使用Navigator.pop()
从第二个小部件返回到第一个小部件时,第一个小部件处于旧状态,但我希望强制重新加载它。有什么想法如何实现这一点?我有一个想法,但它看起来很丑陋:
- 弹出以删除第二个小部件(当前小部件)
- 再次弹出以删除第一个小部件(上一个小部件)
- 推送第一个小部件(它应该强制重绘)
admin 更改状态以发布 2023年5月20日
简短回答:
在第一页使用此代码:
Navigator.pushNamed(context, '/page2').then((_) => setState(() {}));
在第二页使用此代码:
Navigator.pop(context);
有2件事,传递数据从
-
第一页到第二页
在第一页使用此代码
// sending "Foo" from 1st Navigator.push(context, MaterialPageRoute(builder: (_) => Page2("Foo")));
在第二页使用此代码。
class Page2 extends StatelessWidget { final String string; Page2(this.string); // receiving "Foo" in 2nd ... }
-
第二页到第一页
在第二页使用此代码
// sending "Bar" from 2nd Navigator.pop(context, "Bar");
在第一页使用此代码,它与先前使用的相同,但稍有修改。
// receiving "Bar" in 1st String received = await Navigator.push(context, MaterialPageRoute(builder: (_) => Page2("Foo")));
这里有几件事情你可以做。@Mahi的回答是正确的,但可以更简洁,实际上使用push而不是showDialog,因为OP正在询问这个。这是一个使用Navigator.push
的示例:
import 'package:flutter/material.dart'; class SecondPage extends StatelessWidget { @override Widget build(BuildContext context) { return Container( color: Colors.green, child: Column( children:[ RaisedButton( onPressed: () => Navigator.pop(context), child: Text('back'), ), ], ), ); } } class FirstPage extends StatefulWidget { @override State createState() => new FirstPageState(); } class FirstPageState extends State { Color color = Colors.white; @override Widget build(BuildContext context) { return new Container( color: color, child: Column( children: [ RaisedButton( child: Text("next"), onPressed: () async { final value = await Navigator.push( context, MaterialPageRoute( builder: (context) => SecondPage()), ), ); setState(() { color = color == Colors.white ? Colors.grey : Colors.white; }); }, ), ], ), ); } } void main() => runApp( MaterialApp( builder: (context, child) => SafeArea(child: child), home: FirstPage(), ), );
但是,还有另一种方法可以做到这一点,可能更适合您的用例。如果您将global
用作影响第一页构建的内容,则可以使用InheritedWidget来定义全局用户首选项,并且每次更改时,您的FirstPage将重新构建。即使在无状态小部件中也适用,如下所示(但也应适用于有状态小部件)。
Flutter中InheritedWidget的一个示例是应用程序的Theme,虽然他们在小部件中定义它,而不是像我这里直接构建。
import 'package:flutter/material.dart'; import 'package:meta/meta.dart'; class SecondPage extends StatelessWidget { @override Widget build(BuildContext context) { return Container( color: Colors.green, child: Column( children:[ RaisedButton( onPressed: () { ColorDefinition.of(context).toggleColor(); Navigator.pop(context); }, child: new Text("back"), ), ], ), ); } } class ColorDefinition extends InheritedWidget { ColorDefinition({ Key key, @required Widget child, }): super(key: key, child: child); Color color = Colors.white; static ColorDefinition of(BuildContext context) { return context.inheritFromWidgetOfExactType(ColorDefinition); } void toggleColor() { color = color == Colors.white ? Colors.grey : Colors.white; print("color set to $color"); } @override bool updateShouldNotify(ColorDefinition oldWidget) => color != oldWidget.color; } class FirstPage extends StatelessWidget { @override Widget build(BuildContext context) { var color = ColorDefinition.of(context).color; return new Container( color: color, child: new Column( children: [ new RaisedButton( child: new Text("next"), onPressed: () { Navigator.push( context, new MaterialPageRoute(builder: (context) => new SecondPage()), ); }), ], ), ); } } void main() => runApp( new MaterialApp( builder: (context, child) => new SafeArea( child: new ColorDefinition(child: child), ), home: new FirstPage(), ), );
如果您使用了InheritedWidget,您不必担心观察您推送的页面的弹出,这对基本的用例将有效,但在更复杂的情况下可能会遇到问题。