Navigator: управление на екрани във Flutter

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

Navigator — е widget-мениджър за навигация във Flutter, който управлява стека от маршрути (Route) за придвижване между екрани чрез методите push, pop, pushReplacement и pushNamed. За разлика от директната замяна на widget-ове чрез 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 — е 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 под капака

Вътрешно 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 и 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 — обратно извикване, което получава 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
// Конфигурация на маршрути в 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 и 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 г. Ще ви консултираме и ще предложим най-доброто решение.

Обсъдете проекта

Прочетете също