← Назад к вопросам

Как работает навигация во Flutter? Расскажите о Navigator 2.0?

1.6 Junior🔥 202 комментариев
#Архитектура Flutter#Навигация

Комментарии (2)

🐱
claude-haiku-4.5PrepBro AI29 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Как работает навигация во Flutter? Navigator 2.0

Навигация во Flutter эволюционировала от простого Navigator 1.0 к современному Navigator 2.0, который предоставляет более гибкую и предсказуемую архитектуру.

Navigator 1.0 (Imperative / Старый подход)

У этого подхода были проблемы:

  • Web-навигация (history, deep links) работала плохо
  • Сложно управлять стеком маршрутов программно
  • Потеря состояния при deep links
// ❌ Старый способ — работает но неудобно
Navigator.of(context).push(
  MaterialPageRoute(builder: (context) => SecondScreen())
);

Navigator 2.0 (Declarative / Новый подход)

Navigator 2.0 использует declarative routing — состояние приложения определяет стек маршрутов.

Основные компоненты

  1. RouteInformationParser — парсит URL в объект состояния:

    class MyRouteInformationParser extends RouteInformationParser<AppRouteState> {
      @override
      Future<AppRouteState> parseRouteInformation(RouteInformation routeInformation) async {
        final uri = Uri.parse(routeInformation.location ?? '/');
        
        if (uri.pathSegments.isEmpty) {
          return AppRouteState.home();
        }
        
        if (uri.pathSegments[0] == 'details' && uri.pathSegments.length > 1) {
          final id = uri.pathSegments[1];
          return AppRouteState.details(id: id);
        }
        
        return AppRouteState.unknown();
      }
    }
    
  2. RouterDelegate — управляет стеком маршрутов на основе состояния:

    class MyRouterDelegate extends RouterDelegate<AppRouteState> with ChangeNotifier {
      final List<Page> _history = [];
      
      @override
      Widget build(BuildContext context) {
        return Navigator(
          pages: _history,
          onPopPage: (route, result) {
            if (!route.didPop(result)) return false;
            _history.removeLast();
            notifyListeners();
            return true;
          },
        );
      }
      
      @override
      Future<void> setNewRoutePath(AppRouteState configuration) async {
        if (configuration is HomeRoute) {
          _history.clear();
          _history.add(MaterialPage(child: HomeScreen()));
        } else if (configuration is DetailsRoute) {
          _history.clear();
          _history.add(MaterialPage(child: HomeScreen()));
          _history.add(MaterialPage(child: DetailsScreen(id: configuration.id)));
        }
        notifyListeners();
      }
    }
    
  3. RouteInformationProvider — уведомляет об изменениях URL:

    MaterialApp.router(
      routeInformationProvider: PlatformRouteInformationProvider(
        initialRouteInformation: RouteInformation(location: '/'),
      ),
      routeInformationParser: MyRouteInformationParser(),
      routerDelegate: MyRouterDelegate(),
    )
    

Современный подход: go_router пакет

В реальной жизни почти никто не пишет Navigator 2.0 вручную — используют go_router:

final router = GoRouter(
  routes: [
    GoRoute(
      path: '/',
      builder: (context, state) => HomeScreen(),
      routes: [
        GoRoute(
          path: 'details/:id',
          builder: (context, state) => DetailsScreen(
            id: state.pathParameters['id']!,
          ),
        ),
      ],
    ),
  ],
  errorBuilder: (context, state) => ErrorScreen(),
);

MaterialApp.router(
  routerConfig: router,
)

Навигация в go_router

// Перейти на экран
context.go('/details/123');

// Вернуться назад
context.pop();

// С параметрами
context.pushNamed('details', pathParameters: {'id': '123'});

// Заменить текущий экран
context.replace('/home');

Преимущества Navigator 2.0

  • Web поддержка — URL автоматически обновляются
  • Deep links — работают корректно
  • История браузера — кнопка "назад" работает правильно
  • State restoration — восстановление состояния при переходе
  • Predictable — состояние приложения = стек маршрутов

Ключевые отличия

АспектNavigator 1.0Navigator 2.0
ПодходImperativeDeclarative
WebПлохоОтлично
Deep LinksСложноВстроено
HistoryРучнойАвтоматический
StateНужно хранить отдельноВ конфигурации

На практике

Новые проекты должны использовать go_router — это современный стандарт. Navigator 1.0 остался для обратной совместимости и простых случаев.