Navigator: что это, управление экранами в Flutter

Автор: IT Sectr Опубликовано: 2026-07-02 Время чтения: 9 мин

Navigator — это виджет-менеджер навигации во Flutter, управляющий стеком маршрутов (Route) для перемещения между экранами через методы push, pop, pushReplacement и pushNamed. В отличие от прямой замены виджетов через State, Navigator работает на уровне целых экранов: он хранит историю переходов и поддерживает платформенные анимации. По данным Flutter API Reference (2026), Navigator 2.0 (Router) предоставляет декларативное управление навигацией для сложных сценариев с глубокими ссылками и адаптивным дизайном. В типовом приложении Navigator обеспечивает корректное поведение кнопки «Назад» на Android и свайп-жестов на iOS.

Главное

  • Navigator — менеджер навигации, управляющий стеком маршрутов через методы push, pop, pushNamed, pushReplacement и pushAndRemoveUntil
  • Стек маршрутов — Navigator хранит экраны в стеке LIFO: каждый push добавляет экран сверху, pop удаляет верхний
  • pushNamed — навигация по именованным маршрутам, определённым в MaterialApp.routes или onGenerateRoute
  • pushReplacement — замена текущего экрана новым без возможности вернуться к предыдущему (например, после логина)
  • Navigator 2.0 — декларативный API с Router, RouterDelegate и RouteInformationParser для веб- и десктоп-навигации

Что такое Navigator во Flutter

Navigator — это виджет, управляющий стеком Route-объектов, который реализует экранную навигацию в Flutter-приложении. Каждый вызов push помещает новый Route на вершину стека, pop удаляет верхний Route и возвращает на предыдущий экран. MaterialApp автоматически создаёт Navigator для всего приложения, делая его доступным через Navigator.of(context).

В отличие от StatefulWidget, где замена контента происходит через setState внутри одного виджета, Navigator оперирует целыми экранами с собственным жизненным циклом. Каждый Route в стеке — это изолированное состояние с собственным BuildContext, что предотвращает утечки памяти и упрощает управление зависимостями. При вызове pop неиспользуемый Route уничтожается, освобождая ресурсы.

По данным Flutter Navigation Guide (2026), Navigator прошёл эволюцию от императивного API (Navigator 1.0) к декларативному (Navigator 2.0). Navigator 1.0 использует методы push/pop напрямую, что удобно для простых сценариев. Navigator 2.0 (Router) подходит для приложений с глубокими ссылками, адаптивной навигацией и веб-маршрутизацией.

Как Navigator работает под капотом

Внутри Navigator использует Overlay — специальный виджет, который отображает Route один поверх другого. Каждый Route создаёт свою позицию в Overlay с z-индексом, соответствующим глубине в стеке. Это объясняет, почему при push новый экран анимируется поверх предыдущего, а при pop — предыдущий экран уже готов к отображению: он не уничтожался, а оставался в Overlay ниже нового.

Для анимации переходов Navigator использует PageTransitionsTheme, который можно переопределить в ThemeData. Платформенные анимации задаются через CupertinoPageRoute для iOS (слайд справа) и MaterialPageRoute для Android (слайд снизу). Navigator автоматически выбирает правильную анимацию при использовании PlatformRoute.

Navigator предоставляет набор методов для управления стеком Route. Каждый метод решает конкретную задачу навигации — от простого перехода до полной замены истории экранов. Рассмотрим основные методы с примерами использования.

МетодОписаниеСценарий применения
pushДобавляет Route на вершину стекаПереход на новый экран с возможностью возврата
popУдаляет верхний Route из стекаВозврат на предыдущий экран
pushReplacementЗаменяет текущий Route новымПосле логина — экран логина заменяется главным
pushAndRemoveUntilДобавляет Route и удаляет предыдущие до условияВыход на главный экран с очисткой истории
popUntilУдаляет Route из стека до достижения условияВозврат на определённый экран в истории
maybePopВызывает pop только если стек содержит >1 RouteПредотвращение закрытия приложения при случайном нажатии

Push и Pop: базовые операции

Метод push принимает Route и возвращает Future с результатом, переданным при pop. Это позволяет получать данные с экрана, на который перешли. Например, экран выбора даты может вернуть DateTime через Navigator.pop(context, selectedDate). Метод pop без аргумента возвращает null, с аргументом — передаёт значение вызывающему экрану.

PushReplacement: замена экрана

pushReplacement заменяет текущую Route новой, удаляя текущую из стека. Это критично для сценариев, где пользователь не должен возвращаться на предыдущий экран. Типичный пример — экран логина: после успешного входа текущий экран заменяется главным, и кнопка «Назад» не возвращает на форму входа.

Именованные маршруты и onGenerateRoute

Navigator поддерживает навигацию по именованным маршрутам через метод pushNamed. Вместо создания Route напрямую, разработчик указывает строковый идентификатор, и Navigator создаёт Route автоматически на основе конфигурации в MaterialApp. Это упрощает код и централизует определение маршрутов в одном месте.

Именованные маршруты определяются через свойство routes в MaterialApp, где каждый ключ — строка пути, а значение — функция, возвращающая Widget. Для динамических маршрутов (с параметрами) используется onGenerateRoute — callback, который получает RouteSettings и возвращает Route. Это позволяет передавать аргументы через arguments и реализовать глубокую навигацию.

По данным Flutter Cookbook (2026), передача аргументов через pushNamed осуществляется с помощью параметра arguments: Object?. Принимающий экран извлекает аргументы через ModalRoute.of(context)!.settings.arguments, что обеспечивает типобезопасную передачу данных без глобальных переменных или InheritedWidget.

Обработка неизвестных маршрутов

Свойство onUnknownRoute в MaterialApp обрабатывает случаи, когда pushNamed вызван с несуществующим маршрутом. Это полезно для показа экрана 404 или перенаправления на главную страницу. В комбинации с onGenerateRoute он обеспечивает полное покрытие всех возможных навигационных сценариев.

Navigator 2.0 (также известный как Router API) — это декларативный подход к навигации, представленный в Flutter 2.0. В отличие от императивного Navigator 1.0, где разработчик вызывает push/pop, Router управляет навигацией через состояние, автоматически синхронизируя URL браузера с текущим экраном. Это особенно важно для веб-приложений и десктоп-версий.

Архитектура Navigator 2.0 состоит из трёх ключевых компонентов: RouteInformationParser парсит URL в конфигурацию маршрута, RouterDelegate преобразует конфигурацию в список Route, а BackButtonDispatcher обрабатывает системную кнопку «Назад». Такая архитектура делает навигацию полностью предсказуемой и тестируемой.

Для упрощения работы с Navigator 2.0 существуют пакеты-обёртки: go_router (рекомендуемый Google), auto_route и beamer. go_router предоставляет декларативный DSL для определения маршрутов с поддержкой вложенной навигации, редиректов и глубоких ссылок без ручной реализации RouterDelegate. По данным pub.dev (2026), go_router используется в 35% новых Flutter-проектов, предпочитающих декларативный подход.

Рассмотрим пример Navigator с именованными маршрутами и передачей данных между экранами. Код демонстрирует экран списка товаров, переход на детальный экран и возврат с результатом.

dart
// Route configuration in MaterialApp
MaterialApp(
  initialRoute: '/',
  onGenerateRoute: (RouteSettings settings) {
    if (settings.name == '/') {
      return MaterialPageRoute(
        builder: (context) => const ProductListPage(),
      );
    }
    if (settings.name == '/product') {
      final productId = settings.arguments as String;
      return MaterialPageRoute(
        builder: (context) => ProductDetailPage(productId: productId),
      );
    }
    return MaterialPageRoute(
      builder: (context) => const NotFoundPage(),
    );
  },
)

// Navigation with data passing
final result = await Navigator.pushNamed(
  context,
  '/product',
  arguments: 'product_42',
);

// Getting data on the receiving screen
final args = ModalRoute.of(context)!.settings.arguments as String;

// Replace screen after login
Navigator.pushReplacementNamed(context, '/home');

// Clear stack to main screen
Navigator.pushNamedAndRemoveUntil(
  context,
  '/home',
  (route) => false,
);

В примере Navigator.pushNamed передаёт идентификатор товара на детальный экран. При возврате через Navigator.pop(context, updatedProduct) вызывающий экран получает обновлённые данные в переменной result. pushReplacementNamed заменяет текущий экран после авторизации, а pushNamedAndRemoveUntil с условием (route) => false полностью очищает стек, предотвращая возврат к предыдущим экранам.

Часто задаваемые вопросы

В чём разница между Navigator 1.0 и Navigator 2.0?

Navigator 1.0 — императивный API с методами push и pop, удобный для простых мобильных приложений. Navigator 2.0 — декларативный API через Router, RouterDelegate и RouteInformationParser, необходимый для веб-приложений с URL-маршрутизацией, глубокими ссылками и адаптивной навигацией. Для практических проектов рекомендуется go_router как упрощённая обёртка над Navigator 2.0.

Как передать данные между экранами через Navigator?

Данные передаются через аргумент arguments в pushNamed или напрямую через конструктор Route. На принимающем экране данные извлекаются через ModalRoute.of(context)!.settings.arguments. Для возврата данных используйте Navigator.pop(context, result) — вызывающий экран получит результат как значение Future, возвращённой из push.

Почему кнопка «Назад» не возвращает на предыдущий экран?

Это происходит, если текущий экран был открыт через pushReplacement, который удаляет предыдущий Route из стека. В этом случае истории навигации нет, и кнопка «Назад» закрывает приложение. Для возврата используйте обычный push, а не pushReplacement. Проверьте также, что вызов Navigator.pop корректно обрабатывается на текущем экране.

Как предотвратить возврат на предыдущий экран?

Используйте pushReplacement для замены текущего экрана новым — предыдущий экран удаляется из стека, и вернуться на него нельзя. Для полной очистки истории используйте pushAndRemoveUntil с условием (route) => false. Альтернативно можно переопределить WillPopScope (устарел) или PopScope для перехвата системной кнопки «Назад».

Что такое go_router и когда его использовать?

go_router — это декларативный пакет навигации от Google, построенный поверх Navigator 2.0. Он предоставляет простой DSL для определения маршрутов с поддержкой вложенности, редиректов, глубоких ссылок и ShellRoute для BottomNavigationBar. Используйте go_router для новых проектов, особенно если требуется веб-поддержка или сложные навигационные паттерны с защищёнными маршрутами.

Итоги

  • Navigator — менеджер навигации Flutter, управляющий стеком Route с методами push, pop, pushReplacement и pushAndRemoveUntil
  • Стек LIFO — каждый push добавляет Route на вершину, pop удаляет верхний; стек хранит историю переходов по принципу «последним пришёл — первым ушёл»
  • pushReplacement — замена текущего экрана без возможности возврата, критично для сценариев логина и онбординга
  • Именованные маршруты — pushNamed с RouteSettings и onGenerateRoute для централизованного определения маршрутов с передачей аргументов
  • Navigator 2.0 — декларативная навигация через Router, RouterDelegate и RouteInformationParser для веб-глубоких ссылок
  • go_router — рекомендованная Google обёртка над Navigator 2.0 с простым DSL и поддержкой ShellRoute
  • Передача данных — через arguments в pushNamed и возврат результата через Future от push с помощью Navigator.pop(context, value)

Мы разработаем мобильное приложение под ключ

IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.

Обсудить проект

Читайте также