Flutter Can';中间页中使用PUSH替换时的t pop值
我有一个页面,它推送另一个页面并等待返回/弹出的值进行处理。如果可能的话,我希望第二页能够委托(让另一页返回值)。大概是这样的:Flutter Can';中间页中使用PUSH替换时的t pop值,flutter,Flutter,我有一个页面,它推送另一个页面并等待返回/弹出的值进行处理。如果可能的话,我希望第二页能够委托(让另一页返回值)。大概是这样的: // page 1 Navigator.of(context).push(Page2()).then((value) => print(value)); // process value; perhaps setState or whatever // page 2 Navigator.of(context).pushReplacement(Page3());
// page 1
Navigator.of(context).push(Page2()).then((value) => print(value)); // process value; perhaps setState or whatever
// page 2
Navigator.of(context).pushReplacement(Page3()); // let another page handle the rest
// page 3
Navigator.of(context).pop(99);
然而,第一页上的未来永远不会返回,也永远不会打印值(或以我认为合适的方式处理)。推送替换的原因是我不希望用户返回第2页,如果他们已经进入第三页
下面是一个示例颤振应用程序,你可以试试看我的意思
import 'package:flutter/material.dart';
final Color darkBlue = Color.fromARGB(255, 18, 32, 47);
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
debugShowCheckedModeBanner: false,
home: Page1(),
);
}
}
class Page1 extends StatefulWidget {
@override
Page1State createState() => Page1State();
}
class Page1State extends State<Page1> {
List<int> numbers = [];
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
children: <Widget>[
Text('Page 1'),
...numbers.map((number) => Text(number.toString())),
RaisedButton(
child: Text('go to page 2'),
onPressed: () {
Navigator.of(context)
.push(MaterialPageRoute(builder: (context) => Page2()))
.then((number) {
if (number != null) {
setState(() {
numbers.add(number);
});
}
});
},
),
],
),
),
);
}
}
class Page2 extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
children: <Widget>[
Text('Ready?'),
RaisedButton(
child: Text('Yes'),
onPressed: () {
Navigator.of(context).pushReplacement(
MaterialPageRoute(builder: (context) => Page3()));
},
),
RaisedButton(
child: Text('No'),
onPressed: () => Navigator.of(context).pop(),
),
],
),
),
);
}
}
class Page3 extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
children: <Widget>[
Text('Pick a number'),
...[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(
(number) => RaisedButton(
child: Text(number.toString()),
onPressed: () => Navigator.of(context).pop(number),
),
),
RaisedButton(
child: Text('Cancel'),
onPressed: () => Navigator.of(context).pop(),
),
],
),
),
);
}
}
导入“包装:颤振/材料.省道”;
最终颜色深蓝色=颜色。来自argb(255,18,32,47);
void main(){
runApp(MyApp());
}
类MyApp扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
返回材料PP(
主题:ThemeData.dark().copyWith(脚手架背景颜色:深蓝色),
debugShowCheckedModeBanner:false,
主页:第1页(),
);
}
}
类Page1扩展了StatefulWidget{
@凌驾
Page1State createState()=>Page1State();
}
类Page1State扩展状态{
列表编号=[];
@凌驾
小部件构建(构建上下文){
返回脚手架(
正文:中(
子:列(
儿童:[
正文(“第1页”),
…numbers.map((number)=>Text(number.toString()),
升起的按钮(
子项:文本(“转到第2页”),
已按下:(){
导航器(上下文)
.push(MaterialPage路由(生成器:(上下文)=>Page2())
.然后((数字){
如果(数字!=null){
设置状态(){
数字。添加(数字);
});
}
});
},
),
],
),
),
);
}
}
类Page2扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
返回脚手架(
正文:中(
子:列(
儿童:[
文本(“准备好了吗?”),
升起的按钮(
子项:文本('Yes'),
已按下:(){
导航器.of(上下文).pushReplacement(
MaterialPage路由(生成器:(上下文)=>Page3());
},
),
升起的按钮(
child:Text('No'),
onPressed:()=>Navigator.of(context.pop(),
),
],
),
),
);
}
}
类Page3扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
返回脚手架(
正文:中(
子:列(
儿童:[
文本(“选择一个数字”),
…[0,1,2,3,4,5,6,7,8,9,10](
(数字)=>升起按钮(
子项:文本(number.toString()),
按下:()=>Navigator.of(context).pop(number),
),
),
升起的按钮(
子项:文本('Cancel'),
onPressed:()=>Navigator.of(context.pop(),
),
],
),
),
);
}
}
我必须澄清用例。第一个页面将从服务器或其他任何地方获取数据,因此我会使用FutureBuilder或类似工具。第二个页面是创建/添加附加项的表单。表单被提交,如果服务器对数据满意,响应将包含新创建的数据。然后我想用显示数据的成功页面替换当前表单页面。当用户弹出此页面时,我希望第一页的列表用数据更新
可以使用类似Bloc、ValueNotifier或类似的花式状态管理,但此页面寿命很短,我希望使用尽可能少的样板代码实现此功能。另外,我发现如果其他页面需要访问,使用这些状态管理类需要添加到MaterialApp的上方/之前。对于一个可能被我的应用程序深埋的页面,我希望避免在main中添加Bloc/ValueNotifier/任何东西。这感觉太重要了。您可以给
pushReplacement
一个结果,让它返回,就像它被弹出一样
因此,在这种情况下,您可以做的是再次给它一个未来(例如使用补全符),原始推送小部件可以再次等待真正的结果
void方法()异步{
最终完成者=完成者();
最终结果=等待导航仪.pushReplacement(路线,结果:completer.future);
完成(结果);
}
您可以给pushReplacement
一个返回结果,就像它被弹出一样
因此,在这种情况下,您可以做的是再次给它一个未来(例如使用补全符),原始推送小部件可以再次等待真正的结果
void方法()异步{
最终完成者=完成者();
最终结果=等待导航仪.pushReplacement(路线,结果:completer.future);
完成(结果);
}
在这种情况下,您不能使用navigator.pushReplacement,因为它会触发Page1中的回调运行,而该回调将不再可用。回调需要从/通过第2页获取值;仅当从第2页调用Navigator.pop(上下文)时,才会调用第1页中的“then”
Navigator.of(context).pop();
Navigator.of(context).pop(number);
也许您也应该在第一个弹出窗口中包含返回值(数字),以确保它正确到达不确定第二行中的pop是否会在稍后使用此解决方案结束强>
B)也要等待第2页中的导航响应(如第1页),然后在第3页中弹出一次,然后在第2页中弹出一次-此操作不需要命名路由
Navigator.of(context).pop();
Navigator.of(context).pop(number);
也许是
import 'package:flutter/material.dart';
final Color darkBlue = Color.fromARGB(255, 18, 32, 47);
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
debugShowCheckedModeBanner: false,
home: Page1(),
initialRoute: '/page1',
onGenerateRoute: (settings) {
switch (settings.name) {
case '/page1':
return MaterialPageRoute(
settings: RouteSettings(name: '/page1', arguments: Map()),
builder: (_) => Page1(),
);
default:
return null;
}
},
);
}
}
class Page1 extends StatefulWidget {
@override
Page1State createState() => Page1State();
}
class Page1State extends State<Page1> {
List<int> numbers = [];
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('Page 1'),
...numbers.map((number) => Text(number.toString())),
RaisedButton(
child: Text('go to page 2'),
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(builder: (_) => Page2())).then((_) {
final Map arguments = ModalRoute.of(context).settings.arguments as Map;
final int number = arguments['number'] ?? null;
if (number != null) {
setState(() {
numbers.add(number);
});
}
});
},
),
],
),
),
);
}
}
class Page2 extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('Ready?'),
RaisedButton(
child: Text('Yes'),
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(builder: (context) => Page3()));
},
),
RaisedButton(
child: Text('No'),
onPressed: () => Navigator.of(context).pop(),
),
],
),
),
);
}
}
class Page3 extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('Pick a number'),
...[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(
(number) => RaisedButton(
child: Text(number.toString()),
onPressed: () {
Navigator.of(context).popUntil((route) {
if (route.settings.name == '/page1') {
(route.settings.arguments as Map)['number'] = number;
return true;
} else {
return false;
}
});
},
),
),
RaisedButton(
child: Text('Cancel'),
onPressed: () => Navigator.of(context).pop(),
),
],
),
),
);
}
}