Какие классы понадобятся при реализации навигации в Flutter?

Ответ

При реализации навигации в Flutter я работаю со следующими ключевыми классами и концепциями:

1. Navigator — центральный класс, управляющий стеком маршрутов (Route):

// Простой переход
Navigator.push(
  context,
  MaterialPageRoute(builder: (context) => DetailsScreen(product: product)),
);

// Возврат с результатом
final result = await Navigator.push(
  context,
  MaterialPageRoute(builder: (context) => SelectionScreen()),
);

// Возврат назад
Navigator.pop(context, {'selected': true});

2. Route и его реализации:

  • MaterialPageRoute — стандартный маршрут для Material Design
  • CupertinoPageRoute — для iOS-стиля
  • PageRouteBuilder — для кастомных анимаций переходов:
    PageRouteBuilder(
    pageBuilder: (context, animation, secondaryAnimation) => DetailsScreen(),
    transitionsBuilder: (context, animation, secondaryAnimation, child) {
    return FadeTransition(opacity: animation, child: child);
    },
    )

3. RouteSettings — хранение конфигурации маршрута:

Navigator.pushNamed(
  context,
  '/user/profile',
  arguments: UserProfileArgs(userId: 123),
);

// В целевом виджете
final args = ModalRoute.of(context)!.settings.arguments as UserProfileArgs;

4. ModalRoute — для получения информации о текущем маршруте:

final currentRoute = ModalRoute.of(context);
final isCurrent = currentRoute?.isCurrent ?? false;

5. Для именованной навигации (классический подход):

MaterialApp(
  routes: {
    '/': (context) => HomeScreen(),
    '/details': (context) => DetailsScreen(),
    '/settings': (context) => SettingsScreen(),
  },
  onGenerateRoute: (settings) {
    if (settings.name == '/user/:id') {
      final id = settings.name!.split('/').last;
      return MaterialPageRoute(
        builder: (context) => UserScreen(userId: id),
      );
    }
    return null;
  },
);

В современных проектах я часто использую пакеты для более декларативной и типобезопасной навигации:

  • go_router — популярный выбор с глубокими ссылками и guard-логикой
  • auto_route — генерация маршрутов по аннотациям, полная типобезопасность
  • beamer — основан на Router API, поддерживает вложенные маршруты

Ответ 18+ 🔞

Э, слушай, вот сидишь ты такой, пишешь на Flutter, и тут бац — навигация. Ну, на первый взгляд, вроде всё просто: туда перешли, обратно вернулись. Но как начинаешь копать, понимаешь, что там под капотом — ёперный театр, целая вселенная. Давай разберём по косточкам, чтобы не было потом «я нихуя не понял».

1. Navigator — это главный пахан Этот класс — типа диспетчера, который командует целой очередью экранов (стеком маршрутов, если по-умному). Он решает, какой экран сверху, какой скрыт, а какой вообще нахуй послать.

// Самый простой способ ткнуть пользователя на новый экран
Navigator.push(
  context,
  MaterialPageRoute(builder: (context) => DetailsScreen(product: product)),
);

// А вот это уже интереснее: уходим, но ждём ответа, как письма из армии
final result = await Navigator.push(
  context,
  MaterialPageRoute(builder: (context) => SelectionScreen()),
);

// Всё надоело? Возвращаемся обратно, как будто ничего и не было
Navigator.pop(context, {'selected': true});

Без него — никуда. Абсолютный царь и бог.

2. Route — а это уже солдаты, разные и всякие Маршрут — это по сути инструкция, как показать новый экран. Есть стандартные ребята:

  • MaterialPageRoute — для андроидоподобных приложений, с привычной анимацией снизу-вверх.
  • CupertinoPageRoute — для тех, кто любит яблочный стиль, с анимацией справа-налево.
  • PageRouteBuilder — а это для тех, кому стандартные анимации — как серая масса, и хочется своей уникальной хуйни. Тут можно выкручиваться на полную.
PageRouteBuilder(
  pageBuilder: (context, animation, secondaryAnimation) => DetailsScreen(),
  transitionsBuilder: (context, animation, secondaryAnimation, child) {
    // Вот тут уже твори, что хочешь. Например, плавное появление
    return FadeTransition(opacity: animation, child: child);
  },
)

Чувствуешь мощь? Можно сделать так, чтобы экран выезжал на хуй с горы или появлялся, как манда с ушами. Полная свобода, но и ответственность, конечно.

3. RouteSettings — паспорт маршрута Ну, а как передать данные на новый экран, кроме как в конструктор? Вот для этого и есть arguments. Кидаешь что угодно, ловишь на той стороне.

// Кидаем пользователя на профиль и передаём ID
Navigator.pushNamed(
  context,
  '/user/profile',
  arguments: UserProfileArgs(userId: 123), // Любой объект!
);

// А на экране профиля вытаскиваем это добро, как из кармана
final args = ModalRoute.of(context)!.settings.arguments as UserProfileArgs;

Главное — не забыть привести к правильному типу, а то будет null, и волнение ебать.

4. ModalRoute — шпион в стане врага Иногда надо узнать про текущий маршрут: а он активен? а как его зовут? Вот тут и пригодится.

final currentRoute = ModalRoute.of(context);
final isCurrent = currentRoute?.isCurrent ?? false; // true, если экран сейчас виден

Полезная хуйня, когда логика зависит от того, видит ли пользователь этот экран или уже ушёл пить чай.

5. Именованная навигация — чтобы не путаться в пути Когда экранов становится овердохуища, push с MaterialPageRoute превращаются в ад. Тут на помощь приходят именованные маршруты. Прописываешь все пути в одном месте, как карту метро.

MaterialApp(
  routes: {
    '/': (context) => HomeScreen(),
    '/details': (context) => DetailsScreen(),
    '/settings': (context) => SettingsScreen(),
  },
  onGenerateRoute: (settings) { // А это — для динамических путей, типа /user/123
    if (settings.name == '/user/:id') {
      final id = settings.name!.split('/').last;
      return MaterialPageRoute(
        builder: (context) => UserScreen(userId: id),
      );
    }
    return null; // Не нашли? Ну и хуй с ним.
  },
);

Старый, добрый, проверенный способ. Но, чувак, в серьёзных проектах он иногда начинает трещать по швам. Типобезопасность там, глубокие ссылки, логика доступа...

Поэтому в современных проектах все умные дяди берут пакеты:

  • go_router — сейчас, бля, самый модный. Управление через декларативную конфигурацию, охрана маршрутов (guards), глубокие ссылки из коробки. Мощная штука.
  • auto_route — для параноиков, которые хотят полную типобезопасность. Ты описываешь маршруты аннотациями, а пакет генерирует код. Ошибка в названии маршрута? Компилятор тебя нахуй пошлёт сразу, а не в рантайме.
  • beamer — построен на основе низкоуровневого Router API, хорошо заточен под сложные, вложенные навигационные структуры.

Короче, выбор есть. Можно и голым Navigator-ом орудовать, если проект маленький. А можно взять go_router и чувствовать себя повелителем навигации. Главное — понять базовые принципы, а там уже, как говорится, да похуй, какой инструмент использовать, лишь бы работало и не разваливалось при первом же чихе.