Как передавать данные между экранами во Flutter, используя методы push и pop

Как передавать данные между экранами во Flutter, используя методы push и pop

Вопрос передачи данных между экранами является довольно распространенным в ходе разработки мобильных приложений. В данном руководстве мы создадим 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

Read More