Вопрос передачи данных между экранами является довольно распространенным в ходе разработки мобильных приложений. В данном руководстве мы создадим 2 экрана:
1) первый, то есть основной, содержащий кнопку second screen
для открытия второго экрана;
2) второй, на котором расположим кнопку back
, которая позволяет закрыть второй экран и вернуться к первому.
Также продемонстрируем пример передачи данных при открытии нового экрана и при возвращении к предыдущему.
Первый экран:
class FirstScreen extends StatelessWidget {
const FirstScreen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: const Text(
'First Screen',
),
),
body: Center(
child: ElevatedButton(
onPressed: () {
await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const SecondScreen(),
),
);
},
child: const Text('Second Screen'),
),
),
);
}
}
Второй экран:
import 'package:flutter/material.dart';
class SecondScreen extends StatelessWidget {
const SecondScreen({
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: const Text(
'Second Screen',
),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
Navigator.pop(context);
},
child: const Text('Back'),
),
],
),
),
);
}
}
Отправка данных на новый экран
Итак, первое, что нужно помнить: каждый экран во Flutter - это все ещё виджет. Поэтому, для того, чтобы передать какой-либо объект другому экрану, необходимо в данном экране добавить соответствующие свойства.
Добавим следующее свойство типа String
виджету SecondScreen
:
final String screenTitle;
Также необходимо обновить конструктор:
const SecondScreen({
Key? key,
required this.screenTitle,
}) : super(key: key);
Теперь, выведем значение этого свойство в title
виджета AppBar
:
appBar: AppBar(
centerTitle: true,
title: Text(
screenTitle,
),
),
На данном этапе компилятор показывает ошибку, потому что при создании SecondScreen
требует установить значение в свойство screenTitle
. Для того чтобы устранить эту ошибку, необходимо при использовании метода Navigator.push()
изменить создание данного виджета на следующий, тем самым установив строковое значение в нужное свойство:
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const SecondScreen(
screenTitle: 'Screen Title',
),
),
);
Получим, что при нажатии на кнопку SecondScreen
на второй экран будет отправлять строка 'Screen Title', которая служит тайтлом второго экрана.
Возврат данных с экрана
Для того чтобы вернуть данные при закрытии экрана, необходимо добавить второй аргумент методу Navigator.pop()
. Это может быть объект любого типа.
Заменим предыдущую реализацию вызова метода на следующую:
Navigator.pop(context, 'Back button has been pressed');
Для получения данных при закрытии экрана необходимо снова изменить реализацию вызова метода Navigator.push()
:
final result = await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const SecondScreen(
screenTitle: 'Screen Title',
),
),
);
print(result);
Теперь, после нажатия на кнопку Back
на втором экране в переменную result
установится значение 'Back button has been pressed', и в консоль будет выведено значение этой переменной.
Полный исходный код можно найти на GitHub.
Полезные ссылки:
Навигация во Flutter
Именованные маршруты
Передача данных именованному маршруту
Телеграм: https://t.me/the_cybermania
Код: https://github.com/AlexeyShpavda/flutter_navigator_sending_data
Видео: https://www.youtube.com/watch?v=7CluiX90w7Q