1.簡(jiǎn)介
在開發(fā)Flutter開發(fā)的過(guò)程中,路由跳轉(zhuǎn)頁(yè)面是十分常見(jiàn)的,市面上也有許許多多的路由插件包,例如fluro
殷绍、ff_annotation_route
、routermaster
等等鹊漠,但在個(gè)人使用上面主到,還是會(huì)有一些各種各樣的不舒適茶行,于是就開發(fā)了r_router
這個(gè)插件包,我們來(lái)學(xué)習(xí)一下怎么使用吧登钥!非常簡(jiǎn)單
github地址:https://github.com/rhymelph/r_router
2.添加路由路徑
添加路由路徑我們只需要調(diào)用addRoute
方法
- 1.添加單個(gè)路由路徑
RRouter.addRoute(NavigatorRoute(
'/', (ctx) => MyHomePage(title: 'Flutter Demo Home Page')));
- 2.連續(xù)添加多個(gè)路由路徑
RRouter.addRoute(NavigatorRoute('/one', (ctx) => PageOne()))
.addRoute(NavigatorRoute('/two', (ctx) => PageTwo()));
//或者
RRouter.addRoutes([
NavigatorRoute('/one', (ctx) => PageOne()),
NavigatorRoute('/two', (ctx) => PageTwo())
]);
- 3.添加接收路徑參數(shù)路由
RRouter.addRoute(NavigatorRoute(
'/three/:id', (ctx) => PageThree(id: ctx.pathParams.getInt('id'))));
- 4.路徑參數(shù)通過(guò)正則限制(這里只接收數(shù)值類型)
RRouter.addRoute(NavigatorRoute(
'/three/:id',
(ctx) => PageThree(id: ctx.pathParams.getInt('id')),
pathRegEx: {'id': r'^[0-9]*$'},
));
- 5.全匹配
RRouter.addRoute(NavigatorRoute('/four/*', (context) => PageFour()));
- 6.自定義轉(zhuǎn)場(chǎng)動(dòng)畫(默認(rèn)會(huì)使用
FadeUpwardsPageTransitionsBuilder
)
RRouter.addRoute(NavigatorRoute('/five', (ctx) => PageFive(),
defaultPageTransaction: CupertinoPageTransitionsBuilder()));
//設(shè)置全部路由默認(rèn)畔师,也就是替換FadeUpwardsPageTransitionsBuilder
RRouter.setDefaultTransitionBuilder(ZoomPageTransitionsBuilder());
- 7.異步返回頁(yè)面(需自行添加加載對(duì)話框)
RRouter.addRoute(NavigatorRoute('/six', (ctx) async {
Future.delayed(Duration(seconds: 2));
return PageSix();
}));
- 8.覆蓋之前聲明的路由
//后續(xù)插件可自動(dòng)生成這個(gè)路由
RRouter.addRoute(NavigatorRoute('/', (ctx)=>HomePage()));
// 沒(méi)有登錄,重新設(shè)置第一頁(yè)為登錄頁(yè)面
RRouter.addRoute(NavigatorRoute('/', (ctx) => LoginPage()),
isReplaceRouter: true);
- 9.路由可用于處理邏輯
RRouter.addRoute(NavigatorRoute('/baidu/*', (ctx) async {
await Future.delayed(Duration(seconds: 2));
return 'http://www.baidu.com';
}, responseProcessor: (Context ctx, dynamic result) {
launch(result);
// 可以添加返回值怔鳖,只需要 return ,這個(gè)值就會(huì)在navigateTo 返回
}));
- 10.添加攔截器
//單路由路徑添加
RRouter.addRoute(NavigatorRoute('/login', (ctx) => LoginPage(), interceptor: [
(ctx) {
if (isLogin) {
RRouter.navigateTo('/home');
return true;// 返回true為攔截
}
return false;
}
]));
//全局添加
RRouter.addInterceptor((ctx) async {
if (ctx.path == '/two') {
RRouter.navigateTo('/one', body: ctx.body);
return true;
}
return false;
});
- 11.添加路由觀察器
//1. 添加單個(gè)
RRouter.addObserver(RRouterObserver());
//2. 添加多個(gè)
RRouter.addObserver(AnalysisObserver())
.addObserver(ServerReportObserver());
// 或者
RRouter.addObservers([
AnalysisObserver(),
ServerReportObserver(),
]);
- 12.設(shè)置錯(cuò)誤頁(yè)(500)和
Not Found Page
(404)
RRouter.setErrorPage(ErrorPageWrapper(
error:
(BuildContext context, FlutterErrorDetails flutterErrorDetails) =>
Center(
child: Text(
'Exception Page (${flutterErrorDetails.exceptionAsString()})',
),
),
notFound: (BuildContext context, Context ctx) => Material(
child: Center(
child: Text('Page Not found:${ctx.path}'),
),
)));
- 13.重定向頁(yè)面
RRouter.addRoute(NavigatorRoute('/loginPage', (context) {
if(isLogin){
return Redirect(path: '/homePage');
}
return LoginPage();
}));
- 14.設(shè)置非hash路徑
- 設(shè)置為
true
時(shí)茉唉,可以通過(guò)http://localhost:8080/index.html 直接訪問(wèn) - 設(shè)置為
false
時(shí),只能通過(guò)http://localhost:8080/#/index.html 進(jìn)行訪問(wèn)
- 設(shè)置為
RRouter.setPathStrategy(true);
- 15.設(shè)置默認(rèn)Page構(gòu)造器(NAV2.0特有)
當(dāng)我們需要更改過(guò)渡頁(yè)面的動(dòng)畫持續(xù)時(shí)間時(shí)结执,我們可以使用RRouter
的setPageBuilder
方法
RRouter.setPageBuilder((ctx, builder, pageTransitionsBuilder) =>
CustomPage<dynamic>(
child: Builder(
builder: (BuildContext context) => builder.call(context)),
pageTransitionsBuilder: pageTransitionsBuilder,
key: ValueKey(ctx.at.microsecondsSinceEpoch),
name: ctx.path,
arguments: ctx.toJson(),
transitionDuration: Duration(milliseconds: 100),
restorationId: ctx.path));
- 16.設(shè)置只有一個(gè)路由棧時(shí)點(diǎn)擊返回的回調(diào)(NAV2.0特有)
RRouter.setPopHome(() {
//異步邏輯處理
if(currentNow - lastTime > 2000){
showToast(’再點(diǎn)擊一次退出程序‘);
return Future.value(true);
}
return Future.value(false);
}
3.設(shè)置MaterialApp
- 使用Navigator1.0 (一般不適配網(wǎng)頁(yè)的情況下使用)
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
navigatorObservers: [
//new
RRouter.observer,
//new
],
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
- 使用Navigator2.0(墻裂推薦使用)
return MaterialApp.router(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
routerDelegate: RRouter.delegate,
routeInformationParser: RRouter.informationParser,
);
4.路由跳轉(zhuǎn)
- 1.簡(jiǎn)單跳轉(zhuǎn)
RRouter.navigateTo('/one');
- 2.傳隱式參數(shù)(傳遞的內(nèi)容度陆,在Flutter web限制需要可Json化)
RRouter.navigateTo('/two', body: {'param': '我是參數(shù)(支持實(shí)體類,實(shí)體需可JSON化)'});
- 3.傳路徑參數(shù)和查詢參數(shù)
//路徑參數(shù)
RRouter.navigateTo('/three/123');
//查詢參數(shù)
RRouter.navigateTo('/four?id=123');
- 4.跳轉(zhuǎn)可動(dòng)態(tài)設(shè)置跳轉(zhuǎn)動(dòng)畫
//該優(yōu)先級(jí)較高,其次注冊(cè)路由>=默認(rèn)路由
RRouter.navigateTo('/five',pageTransitions: ZoomPageTransitionsBuilder());
- 5.替換模式(替換當(dāng)前棧頂?shù)穆酚桑?/li>
//result 為替換的那個(gè)路由需要返回的內(nèi)容
RRouter.navigateTo('/six',replace: true,result: '返回內(nèi)容');
- 6.棧頂模式(只有當(dāng)前路由不是要跳轉(zhuǎn)的路由献幔,才會(huì)觸發(fā))
RRouter.navigateTo('/seven',isSingleTop: true);
- 7.清空當(dāng)前棧跳轉(zhuǎn)
RRouter.navigateTo('/nine',clearTrace: true);
- 8.獲取上一路由的返回值
//上個(gè)路由調(diào)用
RRouter.pop('123');
//當(dāng)前路由的代碼
final result = await RRouter.navigateTo('/ten');
print(result); // = 123
5.獲取傳值
在注冊(cè)路由時(shí)懂傀,我們可以看到,每次都會(huì)有一個(gè)ctx
,這個(gè)就是上一個(gè)路由跳轉(zhuǎn)的時(shí)候傳遞過(guò)來(lái)的信息蜡感,我們可以通過(guò)這個(gè)參數(shù)獲取path params
,query params
,body
等這些信息蹬蚁,用于滿足大部分需求
參數(shù) | 介紹 |
---|---|
at | 跳轉(zhuǎn)的時(shí)間 |
path | 路徑 |
body | 隱式參數(shù) |
pathParams | 路徑參數(shù) |
queryParams | 查詢參數(shù) |
isDirectly | 是否通過(guò)瀏覽器直接打開 |
//示例一:ctx - pathParams
//添加路由
RRouter.addRoute(NavigatorRoute('/one/:id', (ctx) => PageOne()));
//跳轉(zhuǎn)
RRouter.navigateTo('/one/123');
final id = ctx.pathParams.getInt('id',0); // 獲取路徑參數(shù)
print(id); // = 123
//示例二:ctx - queryParams
//添加路由
RRouter.addRoute(NavigatorRoute('/one', (ctx) => PageOne()));
//跳轉(zhuǎn)
RRouter.navigateTo('/one?id=123');
//ctx 獲取值
final id = ctx.queryParams.getInt('id',0); // 獲取查詢參數(shù)
print(id); // = 123
//示例三:ctx - body
//添加路由
RRouter.addRoute(NavigatorRoute('/one', (ctx) => PageOne()));
//跳轉(zhuǎn)
RRouter.navigateTo('/one',body:123);
//ctx 獲取值
final id = ctx.body; // 獲取隱式參數(shù)
print(id); // = 123
當(dāng)然,在上面返回的PageOne
這個(gè)Widget
下郑兴,我們還可以通過(guò)BuildContext
獲取ctx
class PageOne extends StatefulWidget {
@override
_PageOneState createState() => _PageOneState();
}
class _PageOneState extends State<PageOne> {
@override
Widget build(BuildContext context) {
final ctx = context.readCtx;//獲取傳參
return Scaffold(
appBar: AppBar(
title: Text('普通跳轉(zhuǎn)'),
),
);
}
}
6. 無(wú)需context的展示對(duì)話彈框方法
支持下面的方法
- showRDialog
- showRCupertinoDialog
- showRCupertinoModalPopup
- showRAboutDialog
- showRMenu
- showRTimePicker
- showRGeneralDialog
- showRDatePicker
- showRDateRangePicker
- showRSearch
- showRModalBottomSheet
- showRLicensePage
7.結(jié)尾
上面是本篇文章的所有內(nèi)容犀斋,主要記錄插件如何使用。原理主要是基于RouteSettings
和它的派生類Page
,結(jié)合RouterDelegate
與RouteInformationParser
適配Navigator2.0.參考于jaguar
Dart服務(wù)器開發(fā)框架插件
8.更多內(nèi)容
關(guān)于我的更多插件
-
r_router
路由跳轉(zhuǎn)情连,可實(shí)現(xiàn)路由攔截叽粹,路由注冊(cè),無(wú)Context 跳轉(zhuǎn)却舀、彈對(duì)話框 -
r_logger
日志打印虫几,突破控制臺(tái)輸出最大字?jǐn)?shù)限制 -
r_upgrade
應(yīng)用升級(jí),Android可實(shí)現(xiàn)通知欄下載進(jìn)度挽拔,熱更新辆脸,增量更新,跳轉(zhuǎn)到應(yīng)用商店螃诅,跳轉(zhuǎn)網(wǎng)頁(yè)功能啡氢,IOS實(shí)現(xiàn)跳轉(zhuǎn)App Store,跳轉(zhuǎn)網(wǎng)頁(yè) -
r_scan
二維碼/條形碼掃碼术裸,可自定義掃碼窗口 -
r_calendar
可完全自定義的日歷插件空执,支持多選,連選穗椅,單選,切換同步奶栖,周/月視圖切換等功能 -
r_dotted_line_border
可簡(jiǎn)單實(shí)現(xiàn)虛線邊框匹表,直接在Container
使用 -
r_album
實(shí)現(xiàn)簡(jiǎn)單同步相片到Android/IOS相冊(cè) -
fluct
通過(guò)命令行生成資源文件引用等
dart/Flutter交流群(Dart客棧-同訂閱號(hào)):129380453