Flutter路由管理插件routeborn的使用
Flutter路由管理插件routeborn的使用
简介
routeborn
是一个基于 Flutter 的 Navigator 2.0
的跨平台路由解决方案。它能够轻松处理嵌套导航。
该解决方案基于 Flutter 的 MaterialApp.router
、Router
和 Navigator
组件。
使用方法
基本使用
-
决定
Router
的位置:在你的应用中决定Router
的位置。基本用法是将MaterialApp.router
作为初始的 App 小部件(例如,使用内部包含Router
的MaterialApp
)。其他地方应该直接使用Router
。 -
定义
RoutebornPage
类:根据你的应用逻辑在应用中定义RoutebornPage
类。每个页面都需要有一个RoutebornPage
。例如,查看示例项目中的
favorites_page.dart
文件。你可以在其中看到扩展了RoutebornPage
的FavoritesPage
类。另一个类是FavoritesPageView
,它是一个普通的StatelessWidget
。 -
定义应用的路由:理想的路由定义可以放在一个名为
routes.dart
的单独文件中(例如,查看示例项目的routes.dart
文件)。 -
创建
NavigationNotifier
:在你的应用中某个地方创建NavigationNotifier
,以便在整个应用生命周期内保持其持久性。例如,在根节点的小部件树中使用
StatefulWidget
,或者使用InheritedWidget
或任何你喜欢的状态管理机制(示例项目使用riverpod
包,并将NavigationNotifier
放置在一个Provider
中)。
示例代码
import 'package:example/src/home_page.dart';
import 'package:example/src/page_404.dart';
import 'package:example/src/routes.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:routeborn/routeborn.dart';
void main() {
runApp(const ProviderScope(child: MyApp()));
}
// 初始页面栈
NavigationStack<NestingBranch> initialPages() => NavigationStack(
[AppPageNode(page: HomePage())],
);
// 导航通知器
final navigationNotifierProvider = ChangeNotifierProvider((_) => NavigationNotifier(routes));
// 路由委托
final rootRouterDelegate = Provider((ref) =>
RoutebornRootRouterDelegate(ref.watch(navigationNotifierProvider)));
class MyApp extends HookWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp.router(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
routerDelegate: useProvider(rootRouterDelegate),
routeInformationParser: RoutebornRouteInfoParser(
page404: Page404(),
initialStackBuilder: initialPages,
routes: routes,
),
);
}
}
功能
- 无需
BuildContext
访问导航 - 无需
build_runner
减少 CI/CD 慢速问题 - 基本控制导航栈
pushPage
,popPage
,popUntil
,replaceAllWith
,replaceLastWith
,replaceRootStackWith
和setNestingBranch
用于嵌套导航- 获取导航栈状态:
canPop
,isLastPage<T>
,containsPage<T>
,getNavigationStack
和嵌套导航的getNestingBranch
- 嵌套导航
- 使用
BuildContext
控制父级或子级导航栈 - 无限嵌套(尽管我无法想象高于三级的嵌套)
- 使用
- 内置深度链接
- 对话框、抽屉和其他类型的路由也可以修改 URL
- 路径参数
- 即将支持查询参数
- 即将支持更新 URL 不改变导航栈(例如,"#introduction" 这样的哈希式导航)
- 静态声明路由
- 自动填充栈
- 单个或多个
Router
用于嵌套导航 - 即将支持自定义系统返回键处理
- 即将支持从弹出页面返回参数
限制
- 每个页面必须包含一些常量路径标记
- 不支持无限 URL
- 路由不能是非确定性的
示例用例
在以下导航树结构中,我们可以看到一个可能的导航状态。这是一个虚构的电商应用的例子,也可以在示例应用中看到。
根栈中有三个页面:LoginPage
、HomePage
和 HelpPage
。LoginPage
和 HelpPage
是没有嵌套导航的基本页面。
另一方面,HomePage
是一个使用嵌套导航的页面。嵌套导航通过分支实现。每个分支都有自己的页面堆栈。这些堆栈在切换分支时会被保留。
HomePage
在示例中被 HelpPage
覆盖,后者可能是一个包含额外信息的简单页面。当根栈中的 HelpPage
被弹出后,HomePage
将变得可见。
HomePage
页面可能是一个底部导航栏小部件,对应于嵌套导航的分支。这些标签分别是 Shop
、Favorites
和 Cart
,对应于下面的导航树。
保存堆栈
如下面的导航树所示,所有分支都保留它们的导航堆栈。这意味着,当从 Shop
切换到 Favorites
再切回 Shop
时,Shop
分支的堆栈将被保留。在我们的示例中,产品详情页仍然打开。点击 UI 上的后退按钮后,ProductDetailPage
可以被弹出,而 Shop
分支的导航堆栈中仅剩 ShopPage
。
┌─ LoginPage
├─ HomePage
│ ├─ Branch: Shop
│ │ ├─ ShopPage
│ │ └─ ProductDetailPage
│ ├─ Branch: Favorites
│ │ ├─ FavoritesPage
│ │ └─ ProductDetailPage
│ └─ Branch: Cart
│ └─ CartPage
└─ HelpPage
常见问题解答
是否可以为每个分支使用多个 Router
?
这是必要的,例如当你使用 Flutter 框架中的 CupertinoTabScaffold
时。每个标签有单独的构建器。每个标签需要一个单独的 Router
。
每个这样的 Router
都将有一个 RoutebornNestedRouterDelegate
作为路由器委托。每个 RoutebornNestedRouterDelegate
需要传递一个分支作为参数,对应于标签的分支。
在我们的示例中的 home_page.dart
文件中可以看到 CupertinoTabScaffold
的使用示例。
如果你只需要一个 Router
来处理所有分支,则不需要向 RoutebornNestedRouterDelegate
传递分支参数。
如何自定义页面过渡?
所有 RoutebornPage
默认使用 MaterialPageRoute
的 createRoute
方法。
因此,你可以使用 Theme
中的 pageTransitionsTheme
自定义所有页面的过渡效果。
示例代码:
MaterialApp(
theme: ThemeData(
pageTransitionsTheme: const PageTransitionsTheme(
builders: <TargetPlatform, PageTransitionsBuilder>{
TargetPlatform.android: FadeUpwardsPageTransitionsBuilder(),
TargetPlatform.iOS: CupertinoPageTransitionsBuilder(),
TargetPlatform.linux: FadeUpwardsPageTransitionsBuilder(),
TargetPlatform.macOS: CupertinoPageTransitionsBuilder(),
TargetPlatform.windows: FadeUpwardsPageTransitionsBuilder(),
},
)
)
)
更多关于Flutter路由管理插件routeborn的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter路由管理插件routeborn的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
在Flutter中,路由管理对于应用导航至关重要。routeborn
是一个功能强大的路由管理插件,它提供了灵活和可扩展的路由解决方案。以下是如何在Flutter项目中使用 routeborn
进行路由管理的代码示例。
1. 添加依赖
首先,在你的 pubspec.yaml
文件中添加 routeborn
依赖:
dependencies:
flutter:
sdk: flutter
routeborn: ^最新版本号 # 请替换为实际的最新版本号
然后运行 flutter pub get
以获取依赖。
2. 配置 RouteBorn
在你的主应用文件中(通常是 main.dart
),配置 RouteBorn
:
import 'package:flutter/material.dart';
import 'package:routeborn/routeborn.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp.router(
routerDelegate: RouteBornDelegate(
routes: <String, RouteBornPageBuilder>{
'/': (context, settings) => HomePage(),
'/details': (context, settings) => DetailsPage(arguments: settings.arguments as Map<String, dynamic>),
},
),
routeInformationParser: RouteBornParser(),
);
}
}
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Home Page')),
body: Center(
child: ElevatedButton(
onPressed: () {
Navigator.pushNamed(context, '/details', arguments: {'key': 'value'});
},
child: Text('Go to Details'),
),
),
);
}
}
class DetailsPage extends StatelessWidget {
final Map<String, dynamic> arguments;
DetailsPage({required this.arguments});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Details Page')),
body: Center(
child: Text('Received argument: ${arguments['key']}'),
),
);
}
}
3. 使用命名路由
在上面的示例中,我们使用了命名路由 /
和 /details
。RouteBornDelegate
负责管理这些路由,并根据 URL 路径返回相应的页面。
4. 传递参数
在 HomePage
中,我们通过 Navigator.pushNamed
方法传递了一个参数给 DetailsPage
。在 DetailsPage
中,我们通过构造函数接收这些参数并显示它们。
5. 深度链接和恢复状态
RouteBorn
还支持深度链接和状态恢复。如果你的应用需要处理从外部链接启动并导航到特定页面,或者在应用重新启动时恢复之前的导航状态,RouteBorn
可以帮助你轻松实现这些功能。
例如,你可以通过 URL 启动应用并导航到特定页面:
yourappscheme://details?key=value
然后,在 main.dart
中配置相应的解析逻辑,RouteBorn
会自动处理这些 URL 并导航到正确的页面。
总结
以上示例展示了如何在 Flutter 项目中使用 routeborn
进行路由管理。通过配置 RouteBornDelegate
和 RouteBornParser
,你可以轻松地管理应用中的页面导航和参数传递。如果你需要更高级的功能,如嵌套路由、守卫(guard)等,可以参考 routeborn
的官方文档进行深入了解。