Flutter路由管理插件r_router的使用
Flutter路由管理插件r_router的使用
r_router
r_router是一个Flutter路由包,你可以不使用context来导航,支持对话框/路径正则表达式/自定义导航过渡/Navigator 2.0。
中文介绍
中文介绍请参见这里
开始使用
1. 引入插件
在pubspec.yaml
文件中添加以下代码:
dependencies:
r_router: last version
2. 导入包
在你的Dart文件中添加以下导入语句:
import 'package:r_router/r_router.dart';
简单使用
注册路由
/// [path] 你的路由路径。
/// [handler] 处理Widget ((ctx) => PageOne()))
/// [PageOne] 你的页面。
/// [ctx] 请求数据。
RRouter.addRoute(NavigatorRoute('/one', (ctx) => PageOne()));
在应用中添加路由(Navigator 1.0)
class MyApp extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
// 添加新的观察者
navigatorObservers: [
RRouter.observer,
],
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
在应用中添加路由(Navigator 2.0)
class MyApp extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp.router(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
routerDelegate: RRouter.delegate,
routeInformationParser: RRouter.informationParser,
);
}
}
导航到该页面
/// [path] 你注册的路径。
/// [body] 你想给[path]传递的参数。
/// [replace] 是否替换当前路由。
/// [clearTrace] 是否清除所有路由并推送到[path]。
/// [isSingleTop] 如果[path]已经是顶部,则无响应。
/// [pageTransitions] 你导航时的过渡动画,如果为null则使用默认的Page Transitions Builder。
RRouter.navigateTo('/one');
注册路由
/// 设置错误页面。
RRouter.setErrorPage(ErrorPageWrapper(
error: (BuildContext context, FlutterErrorDetails flutterErrorDetails) =>
Center(
child: Text(
'异常页面 (${flutterErrorDetails.exceptionAsString()})',
),
),
notFound: (BuildContext context, Context ctx) => Material(
child: Center(
child: Text('页面未找到:${ctx.path}'),
),
)));
/// 设置页面构建转换,默认为平台页面过渡。
RRouter.addRoute(NavigatorRoute('/three', (ctx) => PageThree(),
defaultPageTransaction: CupertinoPageTransitionsBuilder()))
不使用context显示对话框
支持以下方法:
- RRouter.showDialog
- RRouter.showCupertinoDialog
- RRouter.showCupertinoModalPopup
- RRouter.showAboutDialog
- RRouter.showMenu
- RRouter.showTimePicker
- RRouter.showGeneralDialog
- RRouter.showDatePicker
- RRouter.showDateRangePicker
- RRouter.showSearch
- RRouter.showModalBottomSheet
- RRouter.showLicensePage
默认Navigator
你可以使用
RRouter.navigator
添加拦截器
RRouter.addInterceptor((ctx) async {
if (ctx.path == '/other') {
RRouter.navigateTo('/five', body: ctx.body);
return true;
}
return false;
});
使用/user/:id或/user/*注册路由路径
RRouter.addRoute(NavigatorRoute('/five/:id', (ctx) => PageFive(id:ctx.pathParams.getInt('id'))));
RRouter.addRoute(NavigatorRoute('/five/*', (ctx) => PageFive()));
从BuildContext获取ctx
Context ctx = context.readCtx;
重定向
RRouter.addRoute(NavigatorRoute('/showDialog', (ctx) async {
return null;
}, responseProcessor: (c, p) async {
await showRDialog(
routeSettings: RouteSettings(name: c.path, arguments: c.body),
builder: (context) => AlertDialog(
title: Text('标题'),
content: Text('内容'),
actions: [
TextButton(
onPressed: () {
Navigator.pop(context);
},
child: Text('确定')),
],
));
return c.isDirectly == true ? Redirect(path: '/') : null;
}));
// 或者
RRouter.addRoute(NavigatorRoute('/showDialog', (ctx) async {
return Redirect(path: '/');
}));
返回首页事件
RRouter.setPopHome(() {
return Future.value(true); // 如果为true将保持,否则将返回首页
})
完整示例Demo
import 'package:flutter/material.dart';
import 'package:r_router/r_router.dart';
import 'package:example/src/page/page_five.dart';
import 'package:example/src/page/page_four.dart';
import 'src/page/my_page.dart';
import 'src/page/page_one.dart';
import 'src/page/page_three.dart';
import 'src/page/page_two.dart';
void main() {
initRouter();
runApp(MyApp());
}
void initRouter() {
// 初始化设置
RRouter.setPathStrategy(true)
.setErrorPage(ErrorPageWrapper(
error: (BuildContext context,
FlutterErrorDetails flutterErrorDetails) =>
Center(
child: Text(
'异常页面 (${flutterErrorDetails.exceptionAsString()})',
),
),
notFound: (BuildContext context, Context ctx) => Material(
child: Center(
child: Text('页面未找到:${ctx.path}'),
),
)))
.addRoute(NavigatorRoute(
'/',
(ctx) => MyHomePage(
title: '我的主页',
)))
.addRoute(NavigatorRoute('/one', (ctx) => PageOne()))
.addRoute(NavigatorRoute(
'/two',
(ctx) => PageTwo(
param: ctx.body != null ? ctx.body['param'] : '',
)))
.addRoute(NavigatorRoute('/three', (ctx) => PageThree(),
defaultPageTransaction: CupertinoPageTransitionsBuilder()))
.addRoute(NavigatorRoute('/four', (ctx) => PageFour(),
defaultPageTransaction: ZoomPageTransitionsBuilder()))
.addRoute(NavigatorRoute('/five', (ctx) => PageFive()))
.addRoute(NavigatorRoute('/five/:id', (ctx) => PageFive()))
.addRoute(NavigatorRoute('/print', (ctx) async {
return Future.value('调用函数');
}, responseProcessor: (c, p) async {
print(p);
return 'hello';
}))
.addRoute(NavigatorRoute('/showDialog', (ctx) async {
return null;
}, responseProcessor: (c, p) async {
await RRouter.showDialog(
routeSettings: RouteSettings(name: c.path, arguments: c.body),
builder: (context) => AlertDialog(
title: Text('标题'),
content: Text('内容'),
actions: [
TextButton(
onPressed: () {
Navigator.pop(context);
},
child: Text('确定')),
],
));
return c.isDirectly == true ? Redirect(path: '/') : null;
}))
.setPageBuilder((ctx, builder, pageTransitionsBuilder) =>
CustomPage<dynamic>(
child: Builder(
builder: (BuildContext context) => builder.call(context)),
buildCustomRoute:
(BuildContext context, CustomPage<dynamic> page) =>
PageBasedCustomPageRoute(
page: page,
pageTransitionsBuilder: pageTransitionsBuilder),
key: ValueKey(ctx.at.microsecondsSinceEpoch),
name: ctx.path,
arguments: ctx.toJson(),
transitionDuration: Duration(milliseconds: 100),
restorationId: ctx.path))
.setPopHome(() {
return Future.value(true);
});
}
class MyApp extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
// 使用Navigator 1.0
// return MaterialApp(
// title: 'Flutter Demo',
// theme: ThemeData(
// primarySwatch: Colors.blue,
// ),
// navigatorObservers: [
// RRouter.observer,
// ],
// home: MyHomePage(title: 'Flutter Demo Home Page'),
// );
// 使用Navigator 2.0
return MaterialApp.router(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
routerDelegate: RRouter.delegate,
routeInformationParser: RRouter.informationParser,
);
}
}
更多关于Flutter路由管理插件r_router的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter路由管理插件r_router的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是一个关于如何使用Flutter路由管理插件r_router
的示例代码。这个示例将展示如何设置基本的路由管理,包括定义路由、导航到新页面以及处理参数传递。
首先,确保你的pubspec.yaml
文件中已经添加了r_router
依赖:
dependencies:
flutter:
sdk: flutter
r_router: ^x.y.z # 请替换为最新版本号
然后运行flutter pub get
来安装依赖。
1. 设置主路由文件
创建一个router.dart
文件来定义你的路由配置。
import 'package:flutter/material.dart';
import 'package:r_router/r_router.dart';
import 'home_page.dart';
import 'detail_page.dart';
class MyRouter extends RRouter {
@override
List<RRoute> get routes => [
RRoute(
path: '/',
builder: (_, __) => HomePage(),
),
RRoute(
path: '/detail/:id',
builder: (_, params) => DetailPage(id: params['id']!),
),
];
}
2. 创建主页(Home Page)
创建一个home_page.dart
文件来定义你的主页。
import 'package:flutter/material.dart';
import 'package:r_router/r_router.dart';
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
final RRouter router = RRouter.of(context);
return Scaffold(
appBar: AppBar(
title: Text('Home Page'),
),
body: Center(
child: ElevatedButton(
onPressed: () {
router.navigateTo('/detail/123');
},
child: Text('Go to Detail Page'),
),
),
);
}
}
3. 创建详情页(Detail Page)
创建一个detail_page.dart
文件来定义你的详情页。
import 'package:flutter/material.dart';
class DetailPage extends StatelessWidget {
final String id;
DetailPage({required this.id});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Detail Page'),
),
body: Center(
child: Text('Detail ID: $id'),
),
);
}
}
4. 在主应用中使用路由
最后,在你的main.dart
文件中使用你定义的路由。
import 'package:flutter/material.dart';
import 'package:r_router/r_router.dart';
import 'router.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
navigatorKey: RRouter.navigatorKey,
onGenerateRoute: (settings) {
final MyRouter router = MyRouter();
return router.generator(settings);
},
home: RRouterScope(
router: MyRouter(),
child: RBuilder(builder: (context, router) {
return router.build('/');
}),
),
);
}
}
在这个示例中,我们定义了一个简单的路由配置,包括一个主页和一个详情页。主页有一个按钮,点击按钮会导航到详情页,并传递一个ID参数。详情页会显示这个ID参数。
r_router
插件允许你以声明式的方式定义路由,并且提供了方便的导航功能。通过这种方式,你可以更好地管理你的Flutter应用中的路由。