欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Flutter中g(shù)o_router路由管理的使用指南

 更新時間:2023年08月24日 08:21:06   作者:島上碼農(nóng)  
go_router?是一個?Flutter?的第三方路由插件,相比?Flutter?自帶的路由,go_router?更加靈活,而且簡單易用,下面小編就來和大家聊聊go_router的使用吧

前言

go_router 是一個 Flutter 的第三方路由插件,相比 Flutter 自帶的路由,go_router 更加靈活,而且簡單易用。在 App 應用中,如果你想自己控制路由的定義和管理方式,那么它將十分有用。同時,對于 Web 應用來說,go_router 也提供了很好的支持。 使用 go_router 后,你可以定義 URL 的格式,使用 URL 跳轉(zhuǎn),處理深度鏈接以及其他一系列的導航相關的應用場景。

GoRouter 特性

GoRouter 針對頁面導航提供了下面這些特性:

  • 使用模板語法解析路由路徑和路由查詢(query)參數(shù);
  • 支持單個目標路由展示多個頁面(子路由);
  • 重定向:可以基于應用狀態(tài)跳轉(zhuǎn)到不同的URL,比如用戶沒有登錄時跳轉(zhuǎn)到登錄頁;
  • 使用 StatefulShellRoute 可以支持嵌套的 Tab 導航;
  • 同時支持 Material 風格和 Cupertino 風格應用;
  • 兼容 Navigator API 。

添加插件

當前最新版本的 go_router 是10.0.0(6.3.0版本以上需要 Dart 2.18),可以根據(jù)自己的需要添加相應的版本。在 pubspec.yaml 中加入依賴的版本即可,下面是以7.1.1版本為例。

dependencies:
  go_router: ^7.1.1

路由配置

引入 go_router 插件后,就可以在應用中配置 GoRouter,代碼如下:

import 'package:go_router/go_router.dart';
// GoRouter configuration
final _router = GoRouter(
  initialLocation: '/',
  routes: [
    GoRoute(
      name: 'home', // Optional, add name to your routes. Allows you navigate by name instead of path
      path: '/',
      builder: (context, state) => HomeScreen(),
    ),
    GoRoute(
      name: 'page2',
      path: '/page2',
      builder: (context, state) => Page2Screen(),
    ),
  ],
);

然后,我們就可以通過MaterialApp.routerCupertinoApp.router構(gòu)造函數(shù)來使用 GoRouter,并且將 routerConfig 參數(shù)設置為我們前面定義的 GoRouter 配置對象。

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp.router(
      routerConfig: _router,
    );
  }
}

接下來就可以愉快地玩耍 GoRouter 了。

路由參數(shù)

GoRouter 的每一個路由都通過 GoRoute對象來配置,我們可以在構(gòu)建 GoRoute 對象時來配置路由參數(shù)。路由參數(shù)典型的就是路徑參數(shù),比如 /path/:{路徑參數(shù)},這個時候 GoRoute的路徑參數(shù)和很多 Web 框架的路由是一樣的,通過一個英文冒號加參數(shù)名稱就可以配置,之后我們可以在回調(diào)方法中通過 GoRouterState 對象獲取路徑參數(shù),這個參數(shù)就可以傳遞到路由跳轉(zhuǎn)目的頁面。

GoRoute(
  path: '/fruits/:id',
  builder: (context, state) {
     final id = state.params['id'] // Get "id" param from URL
     return FruitsPage(id: id);
  },
),

同樣,也可以從GoRouterState中獲取 URL 路徑中的查詢(query)參數(shù),例如下面的代碼就是從/fruits?search=antonio中獲取search參數(shù)。

GoRoute(
  path: '/fruits',
  builder: (context, state) {
    final search = state.queryParams['search'];
    return FruitsPage(search: search);
  },
),

添加子路由

路由匹配后可以支持多個頁面(即子路由),當一個新的頁面在舊的頁面之上展示時,這個時候的效果和調(diào)用 push方法是一樣的,。如果頁面提供了 AppBar 組件的話,那么會自動增加返回按鈕。 要使用子路由,我們只需要在上級路由中增加對應的下級路由即可,代碼如下。

GoRoute(
  path: '/fruits',
  builder: (context, state) {
    return FruitsPage();
  },
  routes: <RouteBase>[ // Add child routes
    GoRoute(
      path: 'fruits-details', // NOTE: Don't need to specify "/" character for router's parents
      builder: (context, state) {
        return FruitDetailsPage();
      },
    ),
  ],
)

頁面導航

GoRouter 提供了多種方式跳轉(zhuǎn)到目的頁面,比如使用context.go()跳轉(zhuǎn)到指定的 URL 地址。

build(BuildContext context) {
  return TextButton(
    onPressed: () => context.go('/fruits/fruit-detail'),
  );
}

也可以使用路由的名稱進行跳轉(zhuǎn),這個時候調(diào)用context.goNamed()即可。

build(BuildContext context) {
  return TextButton(
    // remember to add "name" to your routes
    onPressed: () => context.goNamed('fruit-detail'),
  );
}

如果要構(gòu)建查詢參數(shù),那么可以使用 Uri 類來構(gòu)建路由路徑。

context.go(
  Uri(
    path: '/fruit-detail',
    queryParameters: {'id': '10'},
   ).toString(),
);

如果要從當前頁面返回的話,調(diào)用context.pop()即可。

嵌套導航

有些應用在同一個頁面展示多個子頁面,例如 BottomNavigationBar 在進行導航的時候就可以一直保留在屏幕底部。這種其實是嵌套導航,在 GoRouter 里,可以通過StatefulShellRoute來實現(xiàn)。 StatefulShellRoute不直接使用根導航(root Navigator),而是通過不同的導航的子路由來實現(xiàn)嵌套導航。對于每一個導航分支,都會創(chuàng)建各自獨立的導航,相當于是一個并行導航樹,從而實現(xiàn)了有狀態(tài)的嵌套導航。 當我們使用BottomNavigationBar的時候,就可以為很方便地為每一個 Tab 配置一個持久的導航狀態(tài)。 StatefulShellRoute通過指定一個StatefulShellBranch類型的列表來完成,列表每一個元素代表路由樹的一個獨立的有狀態(tài)的分支。StatefulShellBranch為每個分支提供了根路由和 Navigator key(GlobalKey),并提供了可選的初始默認路由地址。 我們來看看具體怎么實現(xiàn)。 首先創(chuàng)建我們的 GoRouter 對象,這個時候我們需要添加StatefulShellRoute.indexedStack到路由中,這個類負責創(chuàng)建嵌套路由。StatefulShellRoute.indexedStack() 實際上是使用了 IndexedStack創(chuàng)建了一個StatefulShellRoute。 這個構(gòu)造函數(shù)使用IndexedStack來管理每個分支導航的頁面,示例代碼如下:

// Create keys for `root` & `section` navigator avoiding unnecessary rebuilds
final _rootNavigatorKey = GlobalKey<NavigatorState>();
final _sectionNavigatorKey = GlobalKey<NavigatorState>();
final router = GoRouter(
  navigatorKey: _rootNavigatorKey,
  initialLocation: '/feed',
  routes: <RouteBase>[
    StatefulShellRoute.indexedStack(
      builder: (context, state, navigationShell) {
        // Return the widget that implements the custom shell (e.g a BottomNavigationBar).
        // The [StatefulNavigationShell] is passed to be able to navigate to other branches in a stateful way.
        return ScaffoldWithNavbar(navigationShell);
      },
      branches: [
        // The route branch for the 1o Tab
        StatefulShellBranch(
          navigatorKey: _sectionNavigatorKey,
          // Add this branch routes
          // each routes with its sub routes if available e.g feed/uuid/details
          routes: <RouteBase>[
            GoRoute(
              path: '/feed',
              builder: (context, state) => const FeedPage(),
              routes: <RouteBase>[
                GoRoute(
                  path: 'detail',
                  builder: (context, state) => const FeedDetailsPage(),
                )
              ],
            ),
          ],
        ),
        // The route branch for 2o Tab
        StatefulShellBranch(routes: <RouteBase>[
          // Add this branch routes
          // each routes with its sub routes if available e.g shope/uuid/details
          GoRoute(
            path: '/shope',
            builder: (context, state) => const ShopePage(),
          ),
        ])
      ],
    ),
  ],
);

在上面的代碼中,我們在路由中加入了StatefulShellRoute.indexedStack(),由它負責創(chuàng)建路由分支以及返回一個自定義的導航殼,這里是BottomNavigationBar

  • 在 builder 參數(shù)中, 我們返回導航用的殼,一個簡單的帶有BottomNavigationBarScaffold,這里需要記得將navigationShell傳給頁面,因為我們需要用它來導航到其他分支,例如從Home到 Shope。
  • 在路由分支數(shù)組branches中,我們提供了一個StatefulShellBranch 的數(shù)組。這里只需要給第一個元素的navigatorKey提供之前創(chuàng)建的全局的_sectionNavigatorKey。其他分支則使用默認的 key。同時,為每個分支提供了一個RouteBase列表,該列表是對應分支的路由。

下面是我們定義的帶有BottomNavigationBar的自定義導航殼的代碼。

import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
class ScaffoldWithNavbar extends StatelessWidget {
  const ScaffoldWithNavbar(this.navigationShell, {super.key});
  /// The navigation shell and container for the branch Navigators.
  final StatefulNavigationShell navigationShell;
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: navigationShell,
      bottomNavigationBar: BottomNavigationBar(
        currentIndex: navigationShell.currentIndex,
        items: const [
          BottomNavigationBarItem(icon: Icon(Icons.home), label: 'Home'),
          BottomNavigationBarItem(icon: Icon(Icons.shop), label: 'Shope'),
        ],
        onTap: _onTap,
      ),
    );
  }
  void _onTap(index) {
    navigationShell.goBranch(
      index,
      // A common pattern when using bottom navigation bars is to support
      // navigating to the initial location when tapping the item that is
      // already active. This example demonstrates how to support this behavior,
      // using the initialLocation parameter of goBranch.
      initialLocation: index == navigationShell.currentIndex,
    );
  }
}

在上面的代碼中,實際上就是構(gòu)建帶有BottomNavigationBarScaffold然后 body 是從路由里獲取的navigationShell. 路由分支及頁面的切換通過_onTap(index) 實現(xiàn),當點擊某個 Tab 時,就使用navigationShell.goBranch(index)來完成切換動作。完整代碼:flutter-go_router-with-nested-tab-navigation

路由守衛(wèi)(Guards)

有些路由地址需要守衛(wèi),例如對于沒有登錄的用戶,有些頁面就無法訪問。GoRouter 可以設置全局的重定向路由。最常見的一個場景就是對于沒有登錄的用戶,跳轉(zhuǎn)到/login 登錄頁面。 在 GoRouter 中,可以通過redirect 參數(shù)配置重定向,這是一個GoRouterRedirect的回調(diào)方法。如果要基于應用狀態(tài)更改跳轉(zhuǎn)都只,那么既可以在GoRouterGoRoute的構(gòu)造方法中增加redirect參數(shù)。其中 GoRoute是只針對當前路由進行跳轉(zhuǎn)處理,而GoRouter這是全局處理。下面是示例代碼,如果不需要跳轉(zhuǎn),則在回調(diào)方法中返回 null即可。

GoRouter(
  redirect: (BuildContext context, GoRouterState state) {
    final isAuthenticated = // your logic to check if user is authenticated
    if (!isAuthenticated) {
      return '/login';
    } else {
      return null; // return "null" to display the intended route without redirecting
     }
   },
  ...

也可以指定一個redirectLimit參數(shù)來限制最大的跳轉(zhuǎn)次數(shù),這個值默認是5。如果超過了跳轉(zhuǎn)次數(shù),則會顯示一個錯誤頁面。

轉(zhuǎn)場動畫

GoRouter支持為每個 GoRoute自定義轉(zhuǎn)場動畫,這可以通過GoRoute的構(gòu)造函數(shù)的pageBuilder 參數(shù)來完成,下面是示例代碼。

GoRoute(
  path: '/fruit-details',
  pageBuilder: (context, state) {
    return CustomTransitionPage(
      key: state.pageKey,
      child: FruitDetailsScreen(),
      transitionsBuilder: (context, animation, secondaryAnimation, child) {
        // Change the opacity of the screen using a Curve based on the the animation's value
        return FadeTransition(
          opacity: CurveTween(curve: Curves.easeInOutCirc).animate(animation),
          child: child,
        );
      },
    );
  },
),

完整的示例代碼可以在 GitHub 查看:自定義轉(zhuǎn)場動畫源碼。

錯誤處理(404頁面)

go_routerMaterialAppCupertinoApp定義了默認的錯誤頁面,也可以通過 errorBuilder 參數(shù)自定義錯誤頁面,代碼如下。

GoRouter(
  /* ... */
  errorBuilder: (context, state) => ErrorPage(state.error),
);

類型安全路由

除了使用 URL 進行路由導航外,go_router 也通過go_router_builder插件提供了類型安全路由,這可以通過代碼生成來完成。要使用這種方式,需要在pubspec.yaml增加下面這些依賴。

dev_dependencies:
  go_router_builder: ^1.0.16
  build_runner: ^2.3.3
  build_verify: ^3.1.0

定義路由

Then define each route as a class extending GoRouteData and overriding the build method.

class HomeRoute extends GoRouteData {
  const HomeRoute();
  @override
  Widget build(BuildContext context, GoRouterState state) => const HomeScreen();
}

路由樹

路由樹基于每個頂層的路由來定義,代碼如下。

import 'package:go_router/go_router.dart';
part 'go_router.g.dart'; // name of generated file
// Define how your route tree (path and sub-routes)
@TypedGoRoute<HomeScreenRoute>(
    path: '/home',
    routes: [ // Add sub-routes
      TypedGoRoute<SongRoute>(
        path: 'song/:id',
      )
    ]
)
// Create your route screen that extends "GoRouteData" and @override "build"
// method that return the screen for this route
@immutable
class HomeScreenRoute extends GoRouteData {
  @override
  Widget build(BuildContext context) {
    return const HomeScreen();
  }
}
@immutable
class SongRoute extends GoRouteData {
  final int id;
  const SongRoute({required this.id});
  @override
  Widget build(BuildContext context) {
    return SongScreen(songId: id.toString());
  }
}

之后可以運行代碼生成來構(gòu)建類型安全路由。

flutter pub global activate build_runner // Optional, if you already have build_runner activated so you can skip this step
flutter pub run build_runner build

導航的時候,就不再需要使用 URL的方式了,可以構(gòu)建一個GoRouteData對象然后調(diào)用go()即可。

TextButton(
  onPressed: () {
    const SongRoute(id: 2).go(context);
  },
  child: const Text('Go to song 2'),
),

路由跳轉(zhuǎn)監(jiān)測

go_router還提供了一個非常有用的特性,那就是路由導航監(jiān)測NavigatorObserver??梢酝ㄟ^給GoRouter增加一個NavigatorObserver對象來監(jiān)聽路由行為,例如 push、pop 或路由替換(replace)。這可以通過自定義 NavigatorObserver 的子類完成。

class MyNavigatorObserver extends NavigatorObserver {
  @override
  void didPush(Route<dynamic> route, Route<dynamic>? previousRoute) {
    log('did push route');
  }
  @override
  void didPop(Route<dynamic> route, Route<dynamic>? previousRoute) {
    log('did pop route');
  }
}

之后,在GoRouterobservers 參數(shù)中增加自定義的MyNavigatorObserver 即可完成對所有觸發(fā)路由跳轉(zhuǎn)的行為的監(jiān)聽。

GoRouter(
  ...
  observers: [ // Add your navigator observers
    MyNavigatorObserver(),
  ],
...
)

完整的示例代碼見 GitHub: flutter-with-go_router: A simple app to show how to work with go_router。

到此這篇關于Flutter中g(shù)o_router路由管理的使用指南的文章就介紹到這了,更多相關Flutter go_router內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Android水波紋載入控件CircleWaterWaveView使用詳解

    Android水波紋載入控件CircleWaterWaveView使用詳解

    這篇文章主要為大家詳細介紹了Android水波紋載入控件CircleWaterWaveView使用方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-01-01
  • Android Studio設置繪制布局時的視圖

    Android Studio設置繪制布局時的視圖

    這篇文章介紹了Android Studio設置繪制布局時視圖的方法,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-11-11
  • Android如何實現(xiàn)設備的異顯功能詳解

    Android如何實現(xiàn)設備的異顯功能詳解

    這篇文章主要給大家介紹了關于Android如何實現(xiàn)設備的異顯功能的相關資料,這篇文章通過示例代碼介紹的非常詳細,對各位Android開發(fā)者們具有一定的參考學習價值,需要的朋友可以參考下
    2022-02-02
  • Android實現(xiàn)懸浮窗全系統(tǒng)版本

    Android實現(xiàn)懸浮窗全系統(tǒng)版本

    這篇文章主要為大家詳細介紹了Android實現(xiàn)懸浮窗全系統(tǒng)版本,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-11-11
  • Android LayerDrawable使用實例

    Android LayerDrawable使用實例

    這篇文章主要介紹了Android LayerDrawable使用實例,本文講解了LayerDrawable的作用、LayerDrawable的原理、LayerDrawableLayerDrawable的使用實例等,需要的朋友可以參考下
    2015-06-06
  • Android中毛玻璃效果的兩種實現(xiàn)代碼

    Android中毛玻璃效果的兩種實現(xiàn)代碼

    這篇文章主要介紹了Android中毛玻璃效果的兩種實現(xiàn)代碼,第一種是使用JAVA算法FastBlur實現(xiàn),第二種是使用Android自帶類RenderScript 實現(xiàn),本文通過實例代碼介紹的非常詳細,需要的朋友參考下吧
    2024-08-08
  • Android onMeasure與onDraw及自定義屬性使用示例

    Android onMeasure與onDraw及自定義屬性使用示例

    這篇文章主要介紹了Android onMeasure與onDraw及自定義屬性使用示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習吧
    2023-02-02
  • Android WebView基礎應用詳解

    Android WebView基礎應用詳解

    這篇文章主要為大家介紹了Android中WebView這一控件的基礎應用,例如:播放音樂,播放視頻等,文中的示例代碼講解詳細,對于我們了解WebView很有幫助,需要的同學可以學習一下
    2021-12-12
  • Android布局ConstraintLayout代碼修改約束及輔助功能

    Android布局ConstraintLayout代碼修改約束及輔助功能

    這篇文章主要為大家介紹了Android布局ConstraintLayout代碼修改約束及輔助功能示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-09-09
  • Android 仿微信聊天時間格式化顯示功能

    Android 仿微信聊天時間格式化顯示功能

    這篇文章主要介紹了Android 仿微信聊天時間格式化顯示功能,本文中還給大家簡單介紹了在同一年的顯示規(guī)則和不在同一年的顯示規(guī)則。需要的朋友可以參考下
    2017-02-02

最新評論