Flutter路由插件-r_router(全面適配Navigator2.0)

1.簡(jiǎn)介

在開發(fā)Flutter開發(fā)的過(guò)程中,路由跳轉(zhuǎn)頁(yè)面是十分常見(jiàn)的,市面上也有許許多多的路由插件包,例如fluro殷绍、ff_annotation_routeroutermaster等等鹊漠,但在個(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();
}));
RRouter.setPathStrategy(true);
  • 15.設(shè)置默認(rèn)Page構(gòu)造器(NAV2.0特有)
    當(dāng)我們需要更改過(guò)渡頁(yè)面的動(dòng)畫持續(xù)時(shí)間時(shí)结执,我們可以使用RRoutersetPageBuilder方法
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é)合RouterDelegateRouteInformationParser適配Navigator2.0.參考于jaguarDart服務(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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末门坷,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子袍镀,更是在濱河造成了極大的恐慌默蚌,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,402評(píng)論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件苇羡,死亡現(xiàn)場(chǎng)離奇詭異绸吸,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)设江,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門锦茁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人叉存,你說(shuō)我怎么就攤上這事码俩。” “怎么了歼捏?”我有些...
    開封第一講書人閱讀 162,483評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵稿存,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我瞳秽,道長(zhǎng)瓣履,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,165評(píng)論 1 292
  • 正文 為了忘掉前任练俐,我火速辦了婚禮袖迎,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘痰洒。我一直安慰自己瓢棒,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評(píng)論 6 388
  • 文/花漫 我一把揭開白布丘喻。 她就那樣靜靜地躺著脯宿,像睡著了一般。 火紅的嫁衣襯著肌膚如雪泉粉。 梳的紋絲不亂的頭發(fā)上连霉,一...
    開封第一講書人閱讀 51,146評(píng)論 1 297
  • 那天,我揣著相機(jī)與錄音嗡靡,去河邊找鬼跺撼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛讨彼,可吹牛的內(nèi)容都是我干的歉井。 我是一名探鬼主播,決...
    沈念sama閱讀 40,032評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼哈误,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼哩至!你這毒婦竟也來(lái)了躏嚎?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,896評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤菩貌,失蹤者是張志新(化名)和其女友劉穎卢佣,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體箭阶,經(jīng)...
    沈念sama閱讀 45,311評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡虚茶,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了仇参。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片嘹叫。...
    茶點(diǎn)故事閱讀 39,696評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖冈敛,靈堂內(nèi)的尸體忽然破棺而出待笑,到底是詐尸還是另有隱情,我是刑警寧澤抓谴,帶...
    沈念sama閱讀 35,413評(píng)論 5 343
  • 正文 年R本政府宣布暮蹂,位于F島的核電站,受9級(jí)特大地震影響癌压,放射性物質(zhì)發(fā)生泄漏仰泻。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評(píng)論 3 325
  • 文/蒙蒙 一滩届、第九天 我趴在偏房一處隱蔽的房頂上張望集侯。 院中可真熱鬧,春花似錦帜消、人聲如沸棠枉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)辈讶。三九已至,卻和暖如春娄猫,著一層夾襖步出監(jiān)牢的瞬間贱除,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工媳溺, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留月幌,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,698評(píng)論 2 368
  • 正文 我出身青樓悬蔽,卻偏偏與公主長(zhǎng)得像扯躺,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容