Расширенный пакет навигации Flutter
Минималистское руководство по расширенной навигации с использованием Navigator v2.0 во Flutter с AutoRoute
Почему АвтоРут?
Навигатор 2.0 великолепен! но, как и все, мы знаем, что это действительно трудно понять!
В этом случае AutoRoute помогает легко использовать nav2 декларативным способом!
AutoRoute избавляет нас от написания большого количества стандартного кода для классов аргументов-посредников, проверки обязательных аргументов, извлечения аргументов и множества других вещей и т. д.
Почему не другие, а AutoRoute? Потому что это дает нам как довольно короткий синтаксис, так и расширенные функции со стабильностью!
Функции
- Именованные маршруты
- Параметры пути и сопоставление подстановочных знаков
- Вложенные маршруты и маршрутизаторы
- Настраиваемые переходы маршрута
- Глубокие ссылки
- Охранники маршрута
- Простая маршрутизация нижней панели навигации
- Декларативная маршрутизация
- Маршрутизация потока
И многое, многое другое из коробки…
Теперь давайте посмотрим, как его использовать!
Быстрый старт
Шаг 1. Создайте настройки навигации
// @CupertinoAutoRouter // @AdaptiveAutoRouter // @CustomAutoRouter @MaterialAutoRouter( // Name Shortener - HomePage → HomeRoute instead of HomePageRoute replaceInRouteName: 'Page,Route', routes: <AutoRoute>[ AutoRoute(page: HomePage, initial: true), AutoRoute(page: Products), AutoRoute(page: ProductDetailsPage), RedirectRoute(path: '*', redirectTo: '/'), ], ) class $AppRouter {}
Шаг 2
flutter packages pub run build_runner build
Шаг 3
Создайте глобальный экземпляр (также вы можете использовать локатор сервисов, например get_it)
final appRouter = AppRouter();
Шаг 4
class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return MaterialApp.router( routerDelegate: appRouter.delegate(), routeInformationParser: appRouter.defaultRouteParser(), ); } }
Шаг 5
Используйте его, как хотите!
context.push(const ProductsRoute()); // with context appRouter.push(const ProductsRoute()); // without context
Давайте глубоко погрузимся в пакет !!
Прежде чем мы начнем, я хочу сказать, что не буду описывать основные функции, которые есть в каждом пакете! вместо этого я расскажу только о дополнительных функциях, которые делают AutoRoute уникальным и красивым!
Обозреватели (промежуточное ПО)
Будь большим братом, который следит за маршрутом!
class CustomObserver implements AutoRouterObserver { @override void didChangeTabRoute(TabPageRoute route, TabPageRoute previousRoute) {} @override void didInitTabRoute(TabPageRoute route, TabPageRoute? previousRoute) {} @override void didPop(Route route, Route? previousRoute) {} @override void didPush(Route route, Route? previousRoute) {} @override void didRemove(Route route, Route? previousRoute) {} @override void didReplace({Route? newRoute, Route? oldRoute}) {} @override void didStartUserGesture(Route route, Route? previousRoute) {} @override void didStopUserGesture() {} @override NavigatorState? get navigator => throw UnimplementedError(); }
2. Добавьте своего наблюдателя к делегату
MaterialApp.router( routerDelegate: appRouter.delegate( navigatorObservers: () => [
CustomObserver(),FirebaseAnalyticsObserver(analytics: FirebaseAnalytics()), ], ), );
Параметры пути (динамический URL)
Шаг 1. Определите путь
AutoRoute(path: '/books/:bookId', page: BookDetailsPage)
Шаг 2. Аннотируйте параметр в конструкторе
class BookDetailsPage extends StatelessWidget { BookDetailsPage({@pathParam this.bookId});
final int bookId; ...
Параметры запроса
Точно так же можно получить доступ к параметрам запроса!
context.route.queryParams
// or
class BookDetailsPage extends StatelessWidget {
const BookDetailsPage({@queryParam this.id});
final int id;
...
перенаправление
Давайте посмотрим, как легко перенаправить!
<AutoRoute> [
RedirectRoute(path: '/', redirectTo: '/books'),
AutoRoute(path: '/books', page: BooksPage),
]
Подстановочные знаки
Вы хотите использовать подстановочные знаки? без проблем!
AutoRoute(path: '/books/*', page: BooksPage)
RedirectRoute(path: '*', redirectTo: '/')
Глубокие ссылки
MaterialApp.router( routerDelegate: appRouter.delegate(
initialDeepLink: ‘PATH’), );
RouteGuards (промежуточное ПО)
Вы можете легко сделать собственные охранники для ваших маршрутов!
- Создайте свою охрану
class AuthGuard extends AutoRouteGuard { @override void onNavigation(resolver, router) { if(
unauthenticated) resolver.next(true); else router.push(LoginRoute()); } }
2. Назначьте охранников на маршруты, которые вы хотите использовать
AutoRoute(page: ProfileScreen, guards: [AuthGuard]);
3. Запустите генерацию кода и добавьте сгенерированный класс Guard в класс AppRouter.
final _appRouter = AppRouter(authGuard: AuthGuard());
AutoLeadingButton / BackButton
AutoLeadingButton
— это замена AutoRoute кнопки BackButton по умолчанию для обработки вложенного или родительского стека.
AppBar(
leading: AutoLeadingButton(),
...
)
Вложенная навигация
Просто добавьте маршруты в параметр Children, вот и все!!
AutoRoute(
path: '/dashboard',
page: DashboardPage,
children: [
AutoRoute(path: 'users', page: UsersPage),
AutoRoute(path: 'posts', page: PostsPage),
AutoRoute(path: 'settings', page: SettingsPage),
],
)
class DashboardPage extends StatelessWidget { @override Widget build(BuildContext context) { return Row( children: [ Column( children: [
TextButton( child: const Text('Users
'), onPressed: () { appRouter.push(const UsersRoute()); }, ), TextButton( child: const Text('Posts
'), onPressed: () { appRouter.push(constPostsRoute
()); }, ), TextButton( child: const Text('Settings
'), onPressed: () { appRouter.push(constSettingsRoute
()); }, ),], ), Expanded( // nested routes will be rendered here child: AutoRouter(), ), ], ); } }
Навигация по вкладкам
Вам надоела длинная реализация TabBar по умолчанию?
AutoRoute также дает нам довольно удобный способ!
Кстати, вкладки по умолчанию загружаются отложенно, но их тоже можно отключить!
class DashboardPage extends StatelessWidget {
@override
Widget build(context) {
return AutoTabsScaffold(
routes: const [
UsersRoute(),
PostsRoute(),
SettingsRoute(),
],
bottomNavigationBuilder: (_,tabsRouter) {
return BottomNavigationBar(
currentIndex: tabsRouter.activeIndex,
onTap: tabsRouter.setActiveIndex,
items: [
BottomNavigationBarItem(label: 'Users',...),
BottomNavigationBarItem(label: 'Posts',...),
BottomNavigationBarItem(label: 'Settings',...),
],
),
),
}
);
}
Примечание. Вы даже можете реализовать PageView или TabBar, просто добавив конструкторы имен!
AutoTabsRouter.pageView(...);
AutoTabsRouter.tabBar(...);
Вы хотите добраться до контроллеров отовсюду? Это так просто!
router.parent<StackRouter>(); // returns Stack Routing controller
router.parent<TabsRouter>(); // returns Tabs Routing controller
router.root; // returns Stack Routing controller
Вот и все? Нисколько! Есть еще!! Такой как;
- Пользовательские переходы
- Пользовательские конструкторы маршрутов
- Обертывание маршрутов
- RouteAwareStateMixins
- Еще более декларативная навигация и другие…
Для получения дополнительной информации, пожалуйста, ознакомьтесь с документацией!
Спасибо за чтение!
Я постарался объяснить как можно проще. Надеюсь, вам понравится.
Если вам понравилась эта статья, нажмите кнопку 👏 (знали ли вы, что можете дойти до 50?)