Flutter路由管理插件router_management的使用

发布于 1周前 作者 wuwangju 来自 Flutter

Flutter路由管理插件router_management的使用

路由管理

一个为Flutter开发者封装了Navigator 2.0并提供语法糖的插件。

开始使用

通过Flutter CLI安装插件

$ flutter pub add router_management

手动安装插件

打开pubspec.yaml文件,在dependencies:下添加以下内容:

dependencies:
   router_management: ^3.1.0
   ...

使用说明

1. 创建一个继承自NavigationWidgetMixinNavigationWidget,用于构建一个Router

class App extends StatelessWidget with NavigationWidgetMixin {
  App({Key? key}) : super(key: key);

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp.router(
      routeInformationParser: routeInformationParser,
      routerDelegate: routerDelegate,
      title: 'Router Management Example',
      localizationsDelegates: GlobalMaterialLocalizations.delegates,
    );
  }
}

或者

class App extends StatefulWidget with NavigationWidgetMixin {
  App({Key? key}) : super(key: key);

  [@override](/user/override)
  _AppState createState() => _AppState();
}

class _AppState extends State<App> {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp.router(
      routeInformationParser: widget.routeInformationParser,
      routerDelegate: widget.routerDelegate,
      title: 'Router Management Example',
      localizationsDelegates: GlobalMaterialLocalizations.delegates,
    );
  }
}

2. 创建一个代表页面的Widget

class HomeScreen extends StatelessWidget {
  const HomeScreen({Key? key}) : super(key: key);

  // 声明路径
  static const path = '/home/:name';

  // 声明名称
  static const name = 'Home';

  [@override](/user/override)
  Widget build(BuildContext context) {
    final arguments = context.arguments; // 获取页面参数

    return Scaffold(
      body: Center(
        child: Text(
          'Welcome ${arguments.params['name']}',
          style: const TextStyle(fontSize: 32, color: Colors.black),
        ),
      ),
    );
  }
}

3. 在main()方法中实现NavigationRouter

void main() {
  runApp(NavigationRouter(
    child: App(), // 继承自NavigationWidgetMixin的Widget
    pages: [
      NavigationPage(
        path: SplashScreen.path,
        builder: () => const SplashScreen(),
        name: SplashScreen.name,
      ),
      NavigationPage(
        path: HomeScreen.path,
        builder: () => const HomeScreen(),
        name: HomeScreen.name,
      ),
    ], // 页面列表
    initialPage: SplashScreen.path,  // 初始页面路径,默认为"/"
    unknownPage: NavigationPage(
      path: NotFound.path,
      builder: () => const NotFound(),
      name: NotFound.name,
    ), // 当传递未知路径时构建的页面
  ));
}

4. 使用Navigation实例来控制Navigator 2.0

// 使用NavigationService.instance控制Navigator 2.0
NavigatorService.instance.pushReplacement('/home/John Doe');

// 或者使用Router Management扩展在BuildContext上
context.navigator.pushReplacement('/home/John Doe');

5. 使用BuildContext上的扩展来获取路径参数

[@override](/user/override)
Widget build(BuildContext context) {
  final arguments = context.arguments;
  ...
}

6. 持续编码 :)

API

Router Management 提供了许多API来确保可以处理Navigator 2.0。

NavigationRouter

这是实现Navigator 2.0的核心Widget。

Props

名称 描述 是否必需
child 用于构建处理Navigator 2.0实现的Router
pages 用于创建可以通过Navigator 2.0访问的页面
initialPage 用于渲染具有相同路径的页面。如果PageWidget.build返回一个没有RouteInformationProvider的路由器,则将无法正常工作。默认值为"/"
navigatorObservers 用于观察导航器2.0在屏幕之间导航时的情况。默认值为List.empty()
useHash 如果为真,则会使用带有哈希的默认URL策略,例如:flutterexample.dev/#/path/to/screen,否则将是flutterexample.dev/path/to/screen。默认为false
restorationScopeId 用于保存和恢复导航器2.0的状态,如果为null,则状态不会被保存。默认为null
unknownPage 用于创建给定路径的未知页面。默认为null
transitionDuration 用于控制动画过渡。默认为Duration(milliseconds: 400)
transitionsBuilder 用于在导航到另一个页面时构建全局自定义动画过渡。默认:如果平台是web则没有过渡,否则为null

Static Methods

名称 描述
defaultWebTransition 用于获取默认的web过渡,这意味着在导航屏幕之间时没有任何过渡

NavigationRouterGuard

用于验证页面,如果页面不能激活,则将重定向到另一个页面。

Props

名称 描述 是否必需
child 用于构建当页面可以激活时的页面
validation 用于处理页面是否可以激活
placeholder 用于在激活时构建占位符。默认为SizedBox.shrink()
pathToRedirectOnInvalidate 用于在不激活时重定向到页面。如果redirectToUnknownPageOnInvalidatefalse或未设置未知页面,则默认为"/"
redirectToUnknownPageOnInvalidate 用于重定向到未知页面,如果未设置或值为false,则将使用pathToRedirectOnInvalidate。默认为true

NavigationPage

用于在NavigationRouter中创建一个页面。

Props

名称 描述 是否必需
path 页面路径,如:/home。声明页面参数使用此模式/:param-name,然后使用PageArguments.params['param-name']从路径中获取数据,如:/profile/:id
builder 用于构建页面并创建活动页面
fullscreenDialog 用于创建全屏对话框页面。默认为false
maintainState 如果为假,则在导航到另一个页面时将丢弃页面状态。默认为true
transitionDuration 用于控制动画过渡。默认为NavigationRouter.transitionDuration
validators 用于控制页面的激活,当它必须有基本参数之外的其他参数时,如ID或其他内容,如果返回false,则页面将被重定向到初始页面或使用Navigation重定向到另一页面。默认为List.empty()
restorationId 用于保存和恢复页面状态,如果为null,则状态不会被保存。默认为null
name 用于命名页面。默认为null
transitionsBuilder 用于为页面创建自定义过渡。默认为System's Animation Transition

NavigationService

用于获取实际的Navigation实例的核心类。

Static Methods

名称 描述
instance Navigator 2.0的实现

Navigation

用于控制Navigator 2.0的核心导航接口。

Methods

名称 描述
push 用于导航到另一个屏幕,同时保留前一个屏幕
pushReplacement 用于导航到另一个屏幕并替换前一个屏幕
pushAndReplaceUntil 用于导航到另一个屏幕并替换前一个屏幕直到条件返回true
pop 用于导航回前一个屏幕
popAndPush 用于导航回前一个屏幕并导航到另一个屏幕
popUntil 用于导航回前一个屏幕直到条件返回true
pushToUnknownPage 用于导航到未知页面

Getters

名称 描述
canPop 用于了解页面何时可以弹出

PageArguments

用于获取当前页面的参数。

Props

名称 描述
uri 用于获取路径的数据
data 用于获取可以通过Navigation push方法传递的数据
params 用于获取路径的参数
path 用于获取当前路径的快捷方式,相当于Uri.path
paths 用于获取当前路径段的快捷方式,相当于Uri.pathSegments
completePath 用于获取当前完整路径的快捷方式,相当于Uri.toString()
query 用于获取当前查询作为Map<String,String>对象的快捷方式,相当于Uri.queryParameters
queries 用于获取当前查询列表作为Map<String,List<String>>对象的快捷方式,相当于Uri.queryParametersAll

扩展

Router Management 提供了两个扩展以保持代码整洁。

NavigationExtension

用于在BuildContext上获取当前Navigation实例。

Getters

名称 描述
navigator 用于获取当前Navigation实例

PageArgumentsExtension

用于在BuildContext上获取当前PageArguments

Getters

名称 描述
arguments 用于获取当前PageArguments

完整示例Demo

import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:router_management/router_management.dart';

import 'ui/home_screen.dart';
import 'ui/not_found.dart';
import 'ui/profile_screen.dart';
import 'ui/splash_screen.dart';

void main() {
  runApp(
    NavigationRouter(
      child: App(), // The NavigationWidgetMixin that builds a Router
      pages: [
        NavigationPage(
          path: SplashScreen.path,
          builder: () => const SplashScreen(),
          name: SplashScreen.name,
        ),
        NavigationPage(
          path: HomeScreen.path,
          builder: () => const HomeScreen(),
          name: HomeScreen.name,
        ),
        NavigationPage(
          path: ProfileScreen.path,
          builder: () => NavigationRouterGuard(
            child: const ProfileScreen(),
            validation: (args) async {
              if (args.query['name'] == null) return false;

              return true;
            },
          ),
          name: ProfileScreen.name,
        ),
      ], // The pages
      // The initial page's path. Defaults to "/"
      initialPage: SplashScreen.path,
      unknownPage: NavigationPage(
        path: NotFound.path,
        builder: () => const NotFound(),
        name: NotFound.name,
      ), // A page that is built when an unknown path is passed
    ),
  );
}

class App extends StatelessWidget with NavigationWidgetMixin {
  App({Key? key}) : super(key: key);

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp.router(
      routeInformationParser: routeInformationParser,
      routerDelegate: routerDelegate,
      title: 'Router Management Example',
      localizationsDelegates: GlobalMaterialLocalizations.delegates,
    );
  }
}

更多关于Flutter路由管理插件router_management的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter路由管理插件router_management的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何使用 router_management 插件进行 Flutter 路由管理的示例代码。请注意,router_management 并不是 Flutter 社区中广泛认知的一个官方或主流插件,因此这里假设它是一个自定义或第三方插件,并且其功能类似于常见的路由管理插件(如 flutter_navigator 或官方推荐的 flutter/routing)。

由于 router_management 的具体 API 可能与我假设的不同,以下代码将基于一个典型的路由管理插件的功能来编写,你可以根据 router_management 的实际文档进行调整。

1. 添加依赖

首先,在你的 pubspec.yaml 文件中添加 router_management 依赖(假设它存在于 Pub 上):

dependencies:
  flutter:
    sdk: flutter
  router_management: ^x.y.z  # 替换为实际版本号

然后运行 flutter pub get

2. 配置路由

在你的应用中配置路由。通常,这在一个单独的文件中完成,例如 routes.dart

import 'package:flutter/material.dart';
import 'package:router_management/router_management.dart';  // 假设的导入路径
import 'screens/home_screen.dart';
import 'screens/details_screen.dart';

class AppRouter {
  static final Router router = Router(
    routes: [
      RouteDef(path: '/', builder: () => HomeScreen()),
      RouteDef(path: '/details/:id', builder: (context, args) => DetailsScreen(id: args['id'])),
    ],
  );
}

3. 使用 Router Provider

在你的 MaterialApp 中使用 RouterProvider 来提供路由服务:

import 'package:flutter/material.dart';
import 'package:router_management/router_management.dart';  // 假设的导入路径
import 'routes.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return RouterProvider(
      router: AppRouter.router,
      child: MaterialApp(
        title: 'Flutter Demo',
        theme: ThemeData(
          primarySwatch: Colors.blue,
        ),
        home: RouterOutlet(),  // 使用 RouterOutlet 来显示当前路由
      ),
    );
  }
}

4. 导航到不同页面

在你的应用中,你可以使用 NavigatorRouter 提供的 API 来导航到不同的页面。例如,在 HomeScreen 中:

import 'package:flutter/material.dart';
import 'package:router_management/router_management.dart';  // 假设的导入路径

class HomeScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final Router router = RouterProvider.of(context).router;

    return Scaffold(
      appBar: AppBar(
        title: Text('Home Screen'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            router.navigateTo(context, '/details/123');  // 假设的 API
          },
          child: Text('Go to Details'),
        ),
      ),
    );
  }
}

5. 接收路由参数

DetailsScreen 中接收路由参数:

import 'package:flutter/material.dart';
import 'package:router_management/router_management.dart';  // 假设的导入路径

class DetailsScreen extends StatelessWidget {
  final String id;

  DetailsScreen({required this.id});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Details Screen'),
      ),
      body: Center(
        child: Text('Details for ID: $id'),
      ),
    );
  }
}

总结

以上代码展示了如何使用一个假设的 router_management 插件进行基本的路由管理。如果 router_management 的实际 API 与上述代码中的假设不同,请参考其官方文档进行调整。在实际项目中,务必确保你所使用的插件版本与文档相匹配。

回到顶部