Flutter URL路由管理插件url_router的使用

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

Flutter URL路由管理插件url_router的使用

特性

UrlRouter 是一个基于URL的无意见路由实现(采用Navigator 2.0)。它提供了以下特性:

  • 轻松读取和更新当前URL和查询参数。
  • 支持深层链接、受保护的URL和重定向。
  • 在浏览器中支持后退和前进导航。
  • 对于URL到页面映射、通配符等具有完全控制权。

安装

在你的 pubspec.yaml 文件中添加以下依赖项:

dependencies:
  url_router: ^0.2.0

使用

声明 UrlRouter 并实现 onGeneratePages 方法

UrlRouter 需要你声明一个 UrlRouter 实例,并且实现 onGeneratePages 方法。该方法返回一个表示所需导航堆栈的 Page 元素列表。

late final router = UrlRouter(
  // 返回一组 `Page` 实例,这是 Flutter `Navigator` 所期望的
  onGeneratePages: (router) {
    return [
      // 主视图始终存在
      MaterialPage(child: MainView()),
      // 设置视图可以位于主视图之上(并且可以弹出)
      if(router.url == '/settings')... [
         MaterialPage(child: SettingsView()),
      ]
    ];
  },
  // 可选,用于保护或重定向URL
  onChanging: (router, newUrl) {
    if (authorized == false) return '/'; // 重定向到主视图
    return newUrl; // 允许更改
  },
  // 可选,用于包装一些外部UI
  builder: (router, navigator) {
    return Row(
      children: [ 
         const SideBar(), 
         Expanded(child: navigator) 
         ],
    );
  },
);

访问 UrlRouter

你可以在应用程序中的任何位置通过 UrlRouter.of(context) 访问 UrlRouter,或者使用上下文扩展:

  • context.url
  • context.urlPush
  • context.urlPop
  • context.urlRouter

控制URL

UrlRouter 提供了一个小而强大的API来控制URL:

API 描述
.url 读取/更新当前路径
.push 添加路径段
.pop 移除路径段
.onChanging 更改路径前调用,允许保护路径和重定向
.queryParams 读取/更新当前查询参数

外部框架

你可以使用 builder 代理来围绕底层 Navigator 小部件包装持久UI:

final router = UrlRouter(
    builder: (router, navigator) {
      return Row(
        children: [
          SideBar(),
          Expanded(child: navigator),
        ],
      );
    },
);

处理全屏模态框

当你使用围绕 Navigator 的UI,如标题栏或侧边栏时,通常希望显示对话框和底部表单,这些对话框和底部表单应该位于这些UI之上。

这最简单的解决方法是添加第二个 Navigator,位于路由器处理的 Navigator 之上。

final router = UrlRouter(
    builder: (router, navigator) {
      return Navigator(
        onGenerateRoute: (_) {
          return PageRouteBuilder(
            transitionDuration: Duration.zero,
            pageBuilder: (_, __, ___){
                return AppScaffold(body: navigator);
            },
          );
        });
...

使用自定义的 Navigator

为了提供一个完全自定义的导航实现,忽略 builder 代理中的 Widget navigator 参数:

UrlRouter(builder: (_, navigator) => MyApp());

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

1 回复

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


当然,下面是一个关于如何在Flutter项目中使用url_router插件进行URL路由管理的代码案例。这个插件允许你以声明式的方式定义路由,并轻松地管理导航。

首先,确保你已经在pubspec.yaml文件中添加了url_router依赖:

dependencies:
  flutter:
    sdk: flutter
  url_router: ^x.y.z  # 请替换为最新版本号

然后运行flutter pub get来获取依赖。

接下来,让我们一步一步配置和使用url_router

1. 定义路由

首先,你需要定义你的路由。假设你有两个页面:HomePageDetailsPage

import 'package:flutter/material.dart';
import 'package:url_router/url_router.dart';

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Home Page')),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            // 导航到DetailsPage,传递参数
            Navigator.pushNamed(context, '/details', arguments: {'id': 123});
          },
          child: Text('Go to Details'),
        ),
      ),
    );
  }
}

class DetailsPage extends StatelessWidget {
  final Map<String, dynamic> arguments;

  DetailsPage({required this.arguments});

  @override
  Widget build(BuildContext context) {
    final id = arguments['id'] as int?;
    return Scaffold(
      appBar: AppBar(title: Text('Details Page')),
      body: Center(
        child: Text('Details ID: $id'),
      ),
    );
  }
}

2. 配置路由

在你的应用程序的入口文件(通常是main.dart)中配置url_router

import 'package:flutter/material.dart';
import 'package:url_router/url_router.dart';
import 'home_page.dart';
import 'details_page.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp.router(
      routeInformationParser: UrlRouterParser(),
      routerDelegate: MyRouterDelegate(),
    );
  }
}

class MyRouterDelegate extends RouterDelegate<RouteInformation>
    with ChangeNotifier, PopNavigatorRouterDelegate<RouteInformation> {
  @override
  final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();

  @override
  Widget build(BuildContext context) {
    return Navigator(
      key: navigatorKey,
      pages: [
        MaterialPage(
          key: ValueKey('home'),
          child: HomePage(),
        ),
        if (_currentConfiguration?.location == '/details')
          MaterialPage(
            key: ValueKey('details'),
            child: DetailsPage(arguments: _currentConfiguration?.state),
          ),
      ],
      onGenerateRoute: (settings) {
        if (settings.name == '/details') {
          return MaterialPageRoute<void>(
            settings: settings,
            builder: (context) => DetailsPage(arguments: settings.arguments as Map<String, dynamic>),
          );
        }
        return null;
      },
    );
  }

  RouteInformation? _currentConfiguration;

  @override
  Future<void> setNewRoutePath(RouteInformation configuration) async {
    if (configuration.location != _currentConfiguration?.location) {
      _currentConfiguration = configuration;
      if (configuration.location == '/') {
        navigatorKey.currentState!.popUntil((route) => route.isFirst);
      } else if (configuration.location == '/details') {
        navigatorKey.currentState!.pushNamed('/details', arguments: configuration.state);
      } else {
        navigatorKey.currentState!.pushReplacementNamed('/');
      }
      notifyListeners();
    }
  }
}

3. 启动应用

以上代码设置了一个基本的路由系统,其中HomePage是初始页面,点击按钮可以导航到DetailsPage,并传递参数。MyRouterDelegate处理路由配置和导航。

注意事项

  • url_router插件的API可能有所不同,具体取决于你使用的版本。请参考官方文档以获取最新和最准确的信息。
  • 上述示例使用了MaterialPageRoute进行页面导航,如果你的应用使用了Cupertino风格,你可能需要使用CupertinoPageRoute
  • 确保处理所有可能的路由情况,以避免潜在的导航错误。

这个示例展示了如何使用url_router进行基本的URL路由管理。根据你的应用需求,你可能需要扩展或修改这个基础设置。

回到顶部