Flutter路由外掛-r_router(全面適配Navigator2.0)

rhyme_lph發表於2021-08-21

1.簡介

在開發Flutter開發的過程中,路由跳轉頁面是十分常見的,市面上也有許許多多的路由外掛包,例如fluroff_annotation_routeroutermaster等等,但在個人使用上面,還是會有一些各種各樣的不舒適,於是就開發了r_router這個外掛包,我們來學習一下怎麼使用吧!非常簡單

github地址:github.com/rhymelph/r_…

2.新增路由路徑

新增路由路徑我們只需要呼叫addRoute方法

  • 1.新增單個路由路徑
RRouter.addRoute(NavigatorRoute(
    '/', (ctx) => MyHomePage(title: 'Flutter Demo Home Page')));
複製程式碼
  • 2.連續新增多個路由路徑
RRouter.addRoute(NavigatorRoute('/one', (ctx) => PageOne()))
    .addRoute(NavigatorRoute('/two', (ctx) => PageTwo()));
    
//或者

RRouter.addRoutes([
  NavigatorRoute('/one', (ctx) => PageOne()),
  NavigatorRoute('/two', (ctx) => PageTwo())
]);

複製程式碼
  • 3.新增接收路徑引數路由
RRouter.addRoute(NavigatorRoute(
    '/three/:id', (ctx) => PageThree(id: ctx.pathParams.getInt('id'))));
複製程式碼
  • 4.路徑引數通過正則限制(這裡只接收數值型別)
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.自定義轉場動畫(預設會使用FadeUpwardsPageTransitionsBuilder
RRouter.addRoute(NavigatorRoute('/five', (ctx) => PageFive(),
    defaultPageTransaction: CupertinoPageTransitionsBuilder()));

//設定全部路由預設,也就是替換FadeUpwardsPageTransitionsBuilder
RRouter.setDefaultTransitionBuilder(ZoomPageTransitionsBuilder());
複製程式碼
  • 7.非同步返回頁面(需自行新增載入對話方塊)
RRouter.addRoute(NavigatorRoute('/six', (ctx) async {
  Future.delayed(Duration(seconds: 2));
  return PageSix();
}));
複製程式碼
  • 8.覆蓋之前宣告的路由
//後續外掛可自動生成這個路由
RRouter.addRoute(NavigatorRoute('/', (ctx)=>HomePage()));

// 沒有登入,重新設定第一頁為登入頁面
RRouter.addRoute(NavigatorRoute('/', (ctx) => LoginPage()),
    isReplaceRouter: true);
複製程式碼
  • 9.路由可用於處理邏輯
RRouter.addRoute(NavigatorRoute('/baidu/*', (ctx) async {
  Future.delayed(Duration(seconds: 2));
  return 'http://www.baidu.com';
}, responseProcessor: (Context ctx, dynamic result) {
  launch(result);
}));
複製程式碼
  • 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. 新增單個
RRouter.addObserver(RRouterObserver());

//2. 新增多個

RRouter.addObserver(AnalysisObserver())
    .addObserver(ServerReportObserver());
// 或者
RRouter.addObservers([
  AnalysisObserver(),
  ServerReportObserver(),
]);
複製程式碼
  • 11.設定錯誤頁(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}'),
              ),
            )));
複製程式碼

3.設定MaterialApp

  • 使用Navigator1.0 (一般不適配網頁的情況下使用)
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.路由跳轉

  • 1.簡單跳轉
RRouter.navigateTo('/one');
複製程式碼
  • 2.傳隱式引數(傳遞的內容,在Flutter web限制需要可Json化)
RRouter.navigateTo('/two', body: {'param': '我是引數(支援實體類,實體需可JSON化)'});
複製程式碼
  • 3.傳路徑引數和查詢引數
//路徑引數
RRouter.navigateTo('/three/123');

//查詢引數
RRouter.navigateTo('/four?id=123');
複製程式碼
  • 4.跳轉可動態設定跳轉動畫
//該優先順序較高,其次註冊路由>=預設路由
RRouter.navigateTo('/five',pageTransitions: ZoomPageTransitionsBuilder());
複製程式碼
  • 5.替換模式(替換當前棧頂的路由)
//result 為替換的那個路由需要返回的內容
RRouter.navigateTo('/six',replace: true,result: '返回內容');
複製程式碼
  • 6.棧頂模式(只有當前路由不是要跳轉的路由,才會觸發)
RRouter.navigateTo('/seven',isSingleTop: true);
複製程式碼
  • 7.清空當前棧跳轉
RRouter.navigateTo('/nine',clearTrace: true);
複製程式碼
  • 8.獲取上一路由的返回值
//上個路由呼叫
RRouter.pop('123');

//當前路由的程式碼
final result = await RRouter.navigateTo('/ten');
print(result); // = 123
複製程式碼

5.獲取傳值

在註冊路由時,我們可以看到,每次都會有一個ctx,這個就是上一個路由跳轉的時候傳遞過來的資訊,我們可以通過這個引數獲取path params,query params,body等這些資訊,用於滿足大部分需求

//示例一:ctx - pathParams
//新增路由
RRouter.addRoute(NavigatorRoute('/one/:id', (ctx) => PageOne()));
//跳轉
RRouter.navigateTo('/one/123');
final id = ctx.pathParams.getInt('id',0); // 獲取路徑引數
print(id); // = 123

//示例二:ctx - queryParams
//新增路由
RRouter.addRoute(NavigatorRoute('/one', (ctx) => PageOne()));
//跳轉
RRouter.navigateTo('/one?id=123');
//ctx 獲取值
final id = ctx.queryParams.getInt('id',0); // 獲取查詢引數
print(id); // = 123

//示例三:ctx - body
//新增路由
RRouter.addRoute(NavigatorRoute('/one', (ctx) => PageOne()));
//跳轉
RRouter.navigateTo('/one',body:123);
//ctx 獲取值
final id = ctx.body; // 獲取隱式引數
print(id); // = 123
複製程式碼

當然,在上面返回的PageOne這個Widget下,我們還可以通過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('普通跳轉'),
      ),
    );
  }
}
複製程式碼

6. 無需context的展示對話方塊方法

支援下面的方法

  • showRDialog
  • showRCupertinoDialog
  • showRCupertinoModalPopup
  • showRAboutDialog
  • showRMenu
  • showRTimePicker
  • showRGeneralDialog
  • showRDatePicker
  • showRDateRangePicker
  • showRSearch
  • showRModalBottomSheet
  • showRLicensePage

7.結尾

上面是本篇文章的所有內容,主要記錄外掛如何使用。原理主要是基於RouteSettings和它的派生類Page,結合RouterDelegateRouteInformationParser適配Navigator2.0.參考於jaguarDart伺服器開發框架外掛

8.更多內容

關於我的更多外掛

  • r_router路由跳轉,可實現路由攔截,路由註冊,無Context 跳轉、彈對話方塊
  • r_logger日誌列印,突破控制檯輸出最大字數限制
  • r_upgrade應用升級,Android可實現通知欄下載進度,熱更新,增量更新,跳轉到應用商店,跳轉網頁功能,IOS實現跳轉App Store,跳轉網頁
  • r_scan 二維碼/條形碼掃碼,可自定義掃碼視窗
  • r_calendar 可完全自定義的日曆外掛,支援多選,連選,單選,切換同步,周/月檢視切換等功能
  • r_dotted_line_border 可簡單實現虛線邊框,直接在Container使用
  • r_album 實現簡單同步相片到Android/IOS相簿
  • fluct 通過命令列生成資原始檔引用等

dart/Flutter交流群(Dart客棧-同訂閱號):129380453

相關文章