Navigator — е widget-мениджър за навигация във Flutter, който управлява стека от маршрути (Route) за придвижване между екрани чрез методите push, pop, pushReplacement и pushNamed. За разлика от директната замяна на widget-ове чрез State, Navigator работи на ниво цели екрани: съхранява историята на преходите и поддържа платформени анимации. Според Flutter API Reference (2026), Navigator 2.0 (Router) предоставя декларативно управление на навигацията за сложни сценарии с дълбоки връзки и адаптивен дизайн. В типично приложение Navigator осигурява правилното поведение на бутона „Назад" на Android и жестовете за плъзгане на iOS.
Основни точки
Navigator — е widget, който управлява стека от Route обекти и реализира екранна навигация във Flutter приложение. Всяко извикване на push поставя нов Route на върха на стека, pop премахва горния Route и се връща към предишния екран. MaterialApp автоматично създава Navigator за цялото приложение, правейки го достъпен чрез Navigator.of(context).
За разлика от StatefulWidget, където замяната на съдържание става чрез setState в рамките на един widget, 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 — специален widget, който показва 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 — обратно извикване, което получава 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 с именувани маршрути и предаване на данни между екрани. Кодът демонстрира екран със списък на продукти, преход към детайлния екран и връщане с резултат.
// Конфигурация на маршрути в 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(),
);
},
)
// Навигация с предаване на данни
final result = await Navigator.pushNamed(
context,
'/product',
arguments: 'product_42',
);
// Получаване на данни на приемащия екран
final args = ModalRoute.of(context)!.settings.arguments as String;
// Замени екран след влизане
Navigator.pushReplacementNamed(context, '/home');
// Изчисти стека до главния екран
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 г. Ще ви консултираме и ще предложим най-доброто решение.
Прочетете също