В некоторых случаях вы можете захотеть вернуть данные с нового экрана. Например, скажем, вы нажимаете новый экран, который предоставляет пользователю два варианта. Когда пользователь нажимает на опцию, вы хотите сообщить первому экрану о выборе пользователя, чтобы он мог воздействовать на эту информацию.
Вы можете сделать это с помощью метода Navigator.pop(), выполнив следующие действия:
- Определить домашний экран
- Добавить кнопку, которая запускает экран выбора
- Показать экран выбора с двумя кнопками
- Когда кнопка нажата, закройте экран выбора
- Показать снэк-бар на главном экране с выбором
1. Определите домашний экран
На главном экране отображается кнопка. При нажатии запускается экран выбора.
class HomeScreen extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Returning Data Demo'), ), // Create the SelectionButton widget in the next step. body: Center(child: SelectionButton()), ); } }
2. Добавьте кнопку, которая запускает экран выбора
Теперь создайте SelectionButton, который делает следующее:
- Запускает SelectionScreen, когда он коснулся.
- Ожидает, что SelectionScreen вернет результат.
class SelectionButton extends StatelessWidget { @override Widget build(BuildContext context) { return RaisedButton( onPressed: () { _navigateAndDisplaySelection(context); }, child: 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 completes after calling // Navigator.pop on the Selection Screen. final result = await Navigator.push( context, // Create the SelectionScreen in the next step. MaterialPageRoute(builder: (context) => SelectionScreen()), ); } }
3. Показать экран выбора с помощью двух кнопок
Теперь создайте экран выбора, который содержит две кнопки. Когда пользователь нажимает кнопку, это приложение закрывает экран выбора и сообщает домашнему экрану, какая кнопка была нажата.
Этот шаг определяет пользовательский интерфейс. Следующий шаг добавляет код для возврата данных.
class SelectionScreen extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Pick an option'), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children:[ Padding( padding: const EdgeInsets.all(8.0), child: RaisedButton( onPressed: () { // Pop here with "Yep"... }, child: Text('Yep!'), ), ), Padding( padding: const EdgeInsets.all(8.0), child: RaisedButton( onPressed: () { // Pop here with "Nope" }, child: Text('Nope.'), ), ) ], ), ), ); } }
4. При нажатии кнопки закройте экран выбора.
Теперь обновите функцию обратного вызова onPressed() для обеих кнопок. Чтобы вернуть данные на первый экран, используйте метод Navigator.pop(), который принимает необязательный второй аргумент с именем result. Любой результат возвращается в Future в SelectionButton.
Есть кнопка
RaisedButton( onPressed: () { // The Yep button returns "Yep!" as the result. Navigator.pop(context, 'Yep!'); }, child: Text('Yep!'), );
Нет кнопки
RaisedButton( onPressed: () { // The Nope button returns "Nope!" as the result. Navigator.pop(context, 'Nope!'); }, child: Text('Nope!'), );
5. Показать снэк-бар на главном экране с выбором
Теперь, когда вы запускаете экран выбора и ожидаете результата, вы захотите что-то сделать с возвращенной информацией.
В этом случае покажите снэк-бар, отображающий результат, используя метод _navigateAndDisplaySelection() в SelectionButton:
_navigateAndDisplaySelection(BuildContext context) async { final result = await Navigator.push( context, MaterialPageRoute(builder: (context) => SelectionScreen()), ); // After the Selection Screen returns a result, hide any previous snackbars // and show the new result. Scaffold.of(context) ..removeCurrentSnackBar() ..showSnackBar(SnackBar(content: Text("$result"))); }
Полный пример
import 'package:flutter/material.dart'; void main() { runApp(MaterialApp( title: 'Returning Data', home: HomeScreen(), )); } class HomeScreen extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Returning Data Demo'), ), body: Center(child: SelectionButton()), ); } } class SelectionButton extends StatelessWidget { @override Widget build(BuildContext context) { return RaisedButton( onPressed: () { _navigateAndDisplaySelection(context); }, child: 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 completes after calling // Navigator.pop on the Selection Screen. final result = await Navigator.push( context, MaterialPageRoute(builder: (context) => SelectionScreen()), ); // After the Selection Screen returns a result, hide any previous snackbars // and show the new result. Scaffold.of(context) ..removeCurrentSnackBar() ..showSnackBar(SnackBar(content: Text("$result"))); } } class SelectionScreen extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Pick an option'), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children:[ Padding( padding: const EdgeInsets.all(8.0), child: RaisedButton( onPressed: () { // Close the screen and return "Yep!" as the result. Navigator.pop(context, 'Yep!'); }, child: Text('Yep!'), ), ), Padding( padding: const EdgeInsets.all(8.0), child: RaisedButton( onPressed: () { // Close the screen and return "Nope!" as the result. Navigator.pop(context, 'Nope.'); }, child: Text('Nope.'), ), ) ], ), ), ); } }
Данная статься является переводом официальной статьи по ссылке Return data from a screen.