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 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.
Читайте також