При использовании именованных маршрутов и, в частности, метода pushNamed требуется новый способ передачи данных на новый экран, так как рассмотренный в данном руководстве способ теряет свою актуальность для них.
Итак, существует 2 именованных маршрута:
routes: {
'/': (context) => const FirstScreen(),
'/second': (context) => const SecondScreen(),
},
Нашей с вами задачей будет передать строку 'Second Screen' второму экрану из первого. Далее, получить эту строку и установить ее в свойство title
виджета AppBar
.
Отправка и получение данных по именованному маршруту
Для того чтобы передать данные, используя метод pushNamed()
, необходимо воспользоваться его параметром arguments
, который имеет тип Object?
. Это говорит о том, что мы можем передавать абсолютно любой объект другому экрану.
Передача значения напрямую
Мы можем передать title для второго экрана напрямую, установив значение 'Second Screen' в arguments
, следующим образом:
Navigator.pushNamed(
context,
'/second',
arguments: 'Second Screen',
);
Далее, чтобы получить данную строку на втором экране, необходимо в методе build
воспользоваться классом ModalRoute
, затем, свойством settings
и получить arguments
. Не стоит забывать, что arguments
имеет тип Object?
, поэтому необходимо выполнить приведение к нужному типу. В данной ситуации мы передали строку, поэтому приведем ее к строке:
@override
Widget build(BuildContext context) {
final arguments = (ModalRoute.of(context)?.settings.arguments ?? '') as String;
...
}
Примечание: ?? ''
добавлено для того, чтобы не получить ошибку приведения, если arguments
окажутся null
.
Теперь, поскольку в переменной arguments
находится строка, отобразим ее с помощью свойства title
виджета AppBar
:
appBar: AppBar(
centerTitle: true,
title: Text(
arguments,
),
),
Задача выполнена, но есть способ лучше.
Создание модели для передачи данных
Довольно странно, что в arguments
находится только строка, и кто сказал, что там должен быть именно title второго экрана? Гораздо уместнее не передавать строку напрямую, а создать соответствующую модель, которая будет содержать все необходимые данные.
Создадим новую модель, которую назовем SecondScreenArguments
:
class SecondScreenArguments {
final String title;
...
SecondScreenArguments(this.title);
}
В данную модель мы можем включить все необходимые свойства (например, свойство title
), причем мы будем сразу иметь строгую типизацию.
Соответственно, теперь, чтобы передать необходимы данные, мы создадим объект типа SecondScreenArguments
и добавим в него необходимые значения:
Navigator.pushNamed(
context,
'/second',
arguments: SecondScreenArguments('Second Screen'),
);
При получении приведем полученный объект к соответствующему типу:
@override
Widget build(BuildContext context) {
final arguments = (ModalRoute.of(context)?.settings.arguments ?? SecondScreenArguments('')) as SecondScreenArguments;
...
}
И, используя свойство SecondScreenArguments, выведем значение в AppBar.
appBar: AppBar(
centerTitle: true,
title: Text(
arguments.title,
),
),
Альтернативой данному способы может быть создание Map
.
Создание Map<String, dynamic> для передачи данных
Для передачи нескольких значений вместо создания модели можно использовать Map
.
Тогда, создается новый Map
, который устанавливается в arguments
. В нем по соответствующим ключам будут лежать необходимые значения:
Navigator.pushNamed(
context,
'/second',
arguments: {'title': 'Second Screen'},
);
При получении объект приводится к Map<String, dynamic>:
@override
Widget build(BuildContext context) {
final arguments = (ModalRoute.of(context)?.settings.arguments ?? <String, dynamic>{'title': ''}) as Map<String, dynamic>;
...
}
А получение данных осуществляется по соответствующему ключу:
appBar: AppBar(
centerTitle: true,
title: Text(
arguments['title'],
),
),
На практике способ с созданием модели показывает себя лучше всего, но все, конечно, зависит от проекта, над которым вы работаете.
Полезные ссылки:
Навигация во Flutter
Как передавать данные между экранами
Именованные маршруты
Телеграм: https://t.me/the_cybermania
Код: https://github.com/AlexeyShpavda/flutter_navigator_pushnamed_arguments
Видео: https://www.youtube.com/watch?v=gL8DQKQx6Yo