Navigator — это виджет-менеджер навигации во Flutter, управляющий стеком маршрутов (Route) для перемещения между экранами через методы push, pop, pushReplacement и pushNamed. В отличие от прямой замены виджетов через State, Navigator работает на уровне целых экранов: он хранит историю переходов и поддерживает платформенные анимации. По данным Flutter API Reference (2026), Navigator 2.0 (Router) предоставляет декларативное управление навигацией для сложных сценариев с глубокими ссылками и адаптивным дизайном. В типовом приложении Navigator обеспечивает корректное поведение кнопки «Назад» на Android и свайп-жестов на iOS.
Главное
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 использует 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 принимает Route и возвращает Future с результатом, переданным при pop. Это позволяет получать данные с экрана, на который перешли. Например, экран выбора даты может вернуть DateTime через Navigator.pop(context, selectedDate). Метод pop без аргумента возвращает null, с аргументом — передаёт значение вызывающему экрану.
pushReplacement заменяет текущую Route новой, удаляя текущую из стека. Это критично для сценариев, где пользователь не должен возвращаться на предыдущий экран. Типичный пример — экран логина: после успешного входа текущий экран заменяется главным, и кнопка «Назад» не возвращает на форму входа.
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 с именованными маршрутами и передачей данных между экранами. Код демонстрирует экран списка товаров, переход на детальный экран и возврат с результатом.
// 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 — императивный API с методами push и pop, удобный для простых мобильных приложений. Navigator 2.0 — декларативный API через Router, RouterDelegate и RouteInformationParser, необходимый для веб-приложений с URL-маршрутизацией, глубокими ссылками и адаптивной навигацией. Для практических проектов рекомендуется go_router как упрощённая обёртка над Navigator 2.0.
Данные передаются через аргумент 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 — это декларативный пакет навигации от Google, построенный поверх Navigator 2.0. Он предоставляет простой DSL для определения маршрутов с поддержкой вложенности, редиректов, глубоких ссылок и ShellRoute для BottomNavigationBar. Используйте go_router для новых проектов, особенно если требуется веб-поддержка или сложные навигационные паттерны с защищёнными маршрутами.
Итоги
Мы разработаем мобильное приложение под ключ
IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.
Читайте также