从新页面返回数据给上一个页面
在某些情况下,我们可能想要从新页面返回数据。例如,假设我们导航到了一个新页面,向用户呈现两个选项。当用户点击某个选项时,我们需要将用户选择通知给第一个页面,以便它能够处理这些信息!
我们如何实现?使用Navigator.pop
!
步骤
- 定义主页。
- 添加一个打开选择页面的按钮。
- 在选择页面上显示两个按钮。
- 点击一个按钮时,关闭选择的页面。
- 主页上弹出一个snackbar以显示用户的选择。
1. 定义主页
主页将显示一个按钮。点击后,它将打开选择页面!
class HomeScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('Returning Data Demo'),
),
// We'll create the SelectionButton Widget in the next step
body: new Center(child: new SelectionButton()),
);
}
}
2. 添加一个打开选择页面的按钮。
现在,我们将创建我们的SelectionButton。我们的选择按钮将会:
- 点击时启动SelectionScreen
- 等待SelectionScreen返回结果
class SelectionButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new RaisedButton(
onPressed: () {
_navigateAndDisplaySelection(context);
},
child: new Text('Pick an option, any option!'),
);
}
// A method that launches the SelectionScreen and awaits the result from
// Navigator.pop
_navigateAndDisplaySelection(BuildContext context) async {
// Navigator.push returns a Future that will complete after we call
// Navigator.pop on the Selection Screen!
final result = await Navigator.push(
context,
// We'll create the SelectionScreen in the next step!
new MaterialPageRoute(builder: (context) => new SelectionScreen()),
);
}
}
3. 在选择页面上显示两个按钮。
现在,我们需要构建一个选择页面!它将包含两个按钮。当用户点击按钮时,应该关闭选择页面并让主页知道哪个按钮被点击!
现在,我们将定义UI,并确定如何在下一步中返回数据。
class SelectionScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('Pick an option'),
),
body: new Center(
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Padding(
padding: const EdgeInsets.all(8.0),
child: new RaisedButton(
onPressed: () {
// Pop here with "Yep"...
},
child: new Text('Yep!'),
),
),
new Padding(
padding: const EdgeInsets.all(8.0),
child: new RaisedButton(
onPressed: () {
// Pop here with "Nope"
},
child: new Text('Nope.'),
),
)
],
),
),
);
}
}
4. 点击一个按钮时,关闭选择的页面。
现在,我们完成两个按钮的onPressed
回调。为了将数据返回到第一个页面,我们需要使用Navitator.pop
方法。
Navigator.pop
接受一个可选的(第二个)参数result
。如果我们返回结果,它将返回到一个Future
到主页的SelectionButton中!
Yep 按钮
new RaisedButton(
onPressed: () {
// Our Yep button will return "Yep!" as the result
Navigator.pop(context, 'Yep!');
},
child: new Text('Yep!'),
);
Nope 按钮
new RaisedButton(
onPressed: () {
// Our Nope button will return "Nope!" as the result
Navigator.pop(context, 'Nope!');
},
child: new Text('Nope!'),
);
5. 主页上弹出一个snackbar以显示用户的选择。
既然我们正在启动一个选择页面并等待结果,那么我们会想要对返回的信息进行一些操作!
在这种情况下,我们将显示一个显示结果的Snackbar。为此,我们将更新SelectionButton
中的_navigateAndDisplaySelection
方法。
_navigateAndDisplaySelection(BuildContext context) async {
final result = await Navigator.push(
context,
new MaterialPageRoute(builder: (context) => new SelectionScreen()),
);
// After the Selection Screen returns a result, show it in a Snackbar!
Scaffold
.of(context)
.showSnackBar(new SnackBar(content: new Text("$result")));
}
完整的例子
import 'package:flutter/material.dart';
void main() {
runApp(new MaterialApp(
title: 'Returning Data',
home: new HomeScreen(),
));
}
class HomeScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('Returning Data Demo'),
),
body: new Center(child: new SelectionButton()),
);
}
}
class SelectionButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new RaisedButton(
onPressed: () {
_navigateAndDisplaySelection(context);
},
child: new Text('Pick an option, any option!'),
);
}
// A method that launches the SelectionScreen and awaits the result from
// Navigator.pop!
_navigateAndDisplaySelection(BuildContext context) async {
// Navigator.push returns a Future that will complete after we call
// Navigator.pop on the Selection Screen!
final result = await Navigator.push(
context,
new MaterialPageRoute(builder: (context) => new SelectionScreen()),
);
// After the Selection Screen returns a result, show it in a Snackbar!
Scaffold
.of(context)
.showSnackBar(new SnackBar(content: new Text("$result")));
}
}
class SelectionScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('Pick an option'),
),
body: new Center(
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Padding(
padding: const EdgeInsets.all(8.0),
child: new RaisedButton(
onPressed: () {
// Close the screen and return "Yep!" as the result
Navigator.pop(context, 'Yep!');
},
child: new Text('Yep!'),
),
),
new Padding(
padding: const EdgeInsets.all(8.0),
child: new RaisedButton(
onPressed: () {
// Close the screen and return "Nope!" as the result
Navigator.pop(context, 'Nope.');
},
child: new Text('Nope.'),
),
)
],
),
),
);
}
}