Как передать данные именованному маршруту во Flutter, используя метод pushNamed

Как передать данные именованному маршруту во Flutter, используя метод pushNamed

При использовании именованных маршрутов и, в частности, метода 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

Read More