Предисловие.
В этой статье вы узнаете, как переключаться между несколькими окнами в Flutter.
Переход между окнами.
Скопируйте данный код себе в main.dart:
Переход на другое окно, делается с помощью Navigator.push().
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return NewWidget2();
},
),
);
Данный метод, принимает context и route
Navigator.push(context, route);
- context — указывает реальное местонахождение виджета в дереве виджетов.
- route — отвечает, за анимацию перехода на другое окно (виджет), также там указано, на какое окно нужно перейти.
Если вам интересно узнать подробнее про context, то посмотрите видео с официального ютуб канала Flutter. Видео на английском, но там есть русские субтитры.
В качестве route, я использовал MaterialPageRoute (простая анимация перехода), и в builder, вернул виджет нового окна.
MaterialPageRoute(
builder: (context) {
return NewWidget2();
},
),
Во втором окне (NewWidget2), я закрыл текущее окно, с помощью Navigator.pop и вернулся к начальному (NewWidget).
child: TextButton(
onPressed: () {
Navigator.pop(context);
},
child: Text("Prev page"),
),
Все остальное я разбирал в предыдущих статьях.
Теперь, запустите.


В итоге, получили переход между двумя окнами.
Переход между окнами, с помощью путей.
Замените свой код, на это.
Чтобы воспользоваться данным способом, нужно прописать пути до виджетов в MaterialApp в параметре routes.
MaterialApp(
routes: {
'/': (BuildContext context) {
return NewWidget();
},
'/second': (BuildContext context) {
return NewWidget2();
},
},
),
Следующий код.
- к начальному путю /, привязываем окно NewWidget. Кстати, путь /, аналогичен аргументу home: NewWidget.
- к путю /second, привязываем NewWidget2
Обратите внимание, использование ‘/‘ пути и аргумента home, приведет к ошибке.
MaterialApp(
routes: {
'/': (BuildContext context) {
return NewWidget();
},
'/second': (BuildContext context) {
return NewWidget2();
},
},
home: NewWidget()
),
Далее, с помощью Navigator.pushNamed, открываем окно по пути /second.
Navigator.pushNamed(context, '/second');


Результат тот же что и в прошлом варианте.
Передаем значение в окно.
Измените Navigator.pushNamed в первом окне таким образом:
Navigator.pushNamed(context, '/second', arguments: {"someKey": "someValue"});
Данные из аргумента arguments, будут переданы во второе окно.
Чтобы их получить, в методе build второго окна, нужно написать следующее:
@override
Widget build(BuildContext context) {
final arg = ModalRoute.of(context)!.settings.arguments as Map; //Получаем аргументы с предыдущего окна
Теперь, вы можете вытащить данные из карты arg. Например так:
child: TextButton(
onPressed: () {
Navigator.pop(context);
},
child: Text("Prev page ${arg['someKey']}"),
),
В примере, я изменил текст кнопки во втором окне.

Возвращаем значения из окна.
Подобное может понадобится когда, например, нужно открыть окно с настройками и из него достать данные.
Измените свой код, на это.
В первом окне (NewWidget), есть асинхронная, приватная функция _waitForData.
_waitForData(BuildContext context) async {
final result = await Navigator.pushNamed(context, '/second');
print(result);
}
Которая, записывает значение из 2-го окна в переменную result.
final result = await Navigator.pushNamed(context, '/second');
И выводит значение result, в консоль.
print(result);
Дальше, метод _waitForData я повесил на кнопку.
onPressed: () {
_waitForData(context);
},
Во втором окне, при нажатии на кнопку.
onPressed: () {
Navigator.pop(context, "Data from page 2");
},
Идет возврат на предыдущее окно (Navigator.pop), и возвращаются из него данные «Data from page 2».
Все, разобрали. Запустите приложение. Теперь, при переходе с 2-го окна на 1-е, появится строка в консоли.

Итоговый результат.
