Flutter — это продукт от Google, который используется для создания гибридных мобильных приложений на ЯП Dart.

Страница приложения Flutter — это Widget, который представляет собой описание изображенного пользовательского интерфейса. Для создания легитимного приложения потребуется множество подобных страниц, представляющих целый ряд функций. Однако каким образом перемещаться между ними? 

Все просто: используйте класс Navigator, встроенный в Flutter SDK.

Navigator

Navigator — это еще один Widget, управляющий страницами приложения в формате стека. Полноэкранные страницы называются маршрутами при использовании в Navigator. Navigator работает как реализация обычного стека. К нему прилагаются два хорошо известных метода: push и pop.

  1. Push: Метод push используется для добавления еще одного маршрута на вершину текущего стека. Новая страница отображается поверх предыдущей.
  2. Pop: Поскольку Navigator работает как стек, он использует принцип LIFO (Last-In, First-Out). Метод pop удаляет верхний маршрут из стека, а пользователю отображается предыдущая страница.

В этой статье мы рассмотрим:

  1. Два способа навигации
  2. Передачу данных следующей странице.

Normal Navigation.

Есть два способа реализации:

Создание новой страницы с методом push

При использовании этого метода новый маршрут создается с помощью класса MaterialPageRoute, в котором создается новая страница (Widget). Эти два оператора создания заключены в метод push и добавляют страницу на вершину стека.

Рассмотрим этот пример наглядно. В компоненте CustomCard находится кнопка, использующая метод push, в то время как в нем создается новый маршрут и страница.

Widget build(BuildContext context) {
  return Card(
    child: Column(
      children: <Widget>[
        Text('Card $index'),
        FlatButton(
          child: Text("Press Me"),
          onPressed: () {
            Navigator.push(context, MaterialPageRoute<void>(
              builder: (BuildContext context) {
                return Scaffold(
                  appBar: AppBar(title: Text('My Page')),
                  body: Center(
                    child: FlatButton(
                      child: Text('POP'),
                      onPressed: () {
                        Navigator.pop(context);
                      },
                    ),
                  ),
                );
              },
            ));
          }),
    ],
  ));
}

Добавление маршрутов в точку входа приложения

В ретроспективе приложения обладают множеством страниц, чаще всего со сложным кодом, поэтому создавать новые страницы не так просто. Особенно если доступ к странице получают из различных областей. Можно просто запутаться в коде для каждого маршрута.

Таким образом, при использовании второго метода, страница создается один раз, однако добавляется в качестве маршрута в точке входа приложения main.dart. Маршруты названы в качестве путей к файлам, поскольку страницей root приложения является путь /.

Для начала создайте новую страницу приложения следующим образом:

class SecondPage extends StatelessWidget {

@override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Second Page'),
      ),
      body: Center(
        child: RaisedButton(
          child: Text('Back To HomeScreen'),
          color: Theme.of(context).primaryColor,
          textColor: Colors.white,
          onPressed: () => Navigator.pop(context)),
      ),
    );
  }
}

Затем импортируйте новую страницу в файле main.dart и добавьте ее в список маршрутов в конструкторе MaterialApp.

class MyApp extends StatelessWidget {
// This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.green,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
      routes: <String, WidgetBuilder>{
        '/a': (BuildContext context) => SecondPage(),
      });
  }
}

Затем отредактируйте метод onPressed кнопки FlatButton в CustomCard на следующее:

Navigator.pushNamed(context, '/a');

В приведенном выше примере пользователь перенаправляется в класс SecondPage, поскольку он является соответствующей страницей пути /a.

Передача данных между страницами

Для передачи данных следующей странице потребуется использование обоих методов навигации, приведенных выше.

Как pushNamed, так и создание нового маршрута в методе push, можно использовать для передачи данных следующей странице. При использовании второго способа не нужно создавать новую страницу. Параметр строителя MaterialPageRoute вызовет конструктор класса SecondPage.

Обновите класс SecondPage для принятия переданных данных следующим образом:

class SecondPage extends StatelessWidget {  
SecondPage({@required this.title});

final title;

@override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Card No. $title'),
      ),
      body: Center(...),
    );
  }
}

Отредактируйте кнопку FlatButtons метода onPressed следующим образом:

Navigator.push( context,
  MaterialPageRoute(
    builder: (context) => SecondPage(title: index)
  )
);

Или так:

Navigator.pushNamed( context, '/a', 
  arguments: <String, String>{
    'title': index + "",
  },
);

Индекс карты передан в класс SecondPage и отображается в AppBar.

Спасибо за внимание! Репозиторий можно найти здесь.


Перевод статьи Sameeha Rahman: How to handle navigation in your Flutter apps

Предыдущая статьяПроблемы при использовании отзывчивого веб-дизайна
Следующая статьяПочему за способностью объяснения модели стоит будущее Data Science