Flutter路由管理插件flyroutes的使用

Flutter路由管理插件flyroutes的使用

FlyRoute

FlyRoute 是一个类似 IndexedStack 的控件,但它使用字符串作为键,并具有许多额外的功能,如子视图嵌套、自定义动画和路径参数。


🛠️ 安装

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

dependencies:
  flyRoute: ^1.2.1

然后运行以下命令以安装依赖项:

flutter pub get

⚙ 导入

在 Dart 文件中导入 flyRoute 库:

import 'package:flyRoute/flyRoute.dart';

🕹️ 使用

要配置 flyRoute,可以通过设置 .routes 属性来提供路由表。声明您想要支持的路径及其对应的视图:

String currentPath = "page1";

// 配置 flyRoute
return flyRoute(
  path: currentPath, // 当前路径
  unknownPathBuilder: (_) => Custom404Page(), // 自定义 404 页面
  routes: {
    ["page1"]: (_) => Page1(), // 路径 page1 对应的页面
    ["page2"]: (_) => Page2(), // 路径 page2 对应的页面
  },
);

注意:一个路由可以匹配多个路径值。例如,当 path 值为 //home 时,以下代码将匹配:

["home", "/"]: (_) => Home(),

📌 相对路径

通过将一个 flyRoute 包裹在另一个 flyRoute 中,可以轻松声明相对路径。例如,定义一个简单的嵌套结构:

return flyRoute(
  path: path,
  routes: {
    ["home"]: (_) => HomePage(),
    ["news"]: (_) => NewsPage(),
    ["settings/"]: (_) => PflyRoute(
      routes: {
        ["profile", ""]: (_) => ProfilePage(), // 匹配 /settings/profile 和 /settings/
        ["notifications"]: (_) => NotificationsPage(), // 匹配 /settings/notifications
      },
    ),
  },
);

这将生成以下潜在路径:

  • /home
  • /news
  • /settings/profile
  • /settings/notifications

🏆 Scaffold 构建器与嵌套

为了支持共享导航或应用框架(如标签页),可以使用 scaffoldBuilder 来包裹当前 flyRoute 子视图。例如,创建一个基本的标签页框架:

return flyRoute(
  path: currentPath,
  scaffoldBuilder: (_, child) => TabScaffold(
    child: child,
    onTabPressed: (value) {
      setState(() => _currentPath = value); // 更新当前路径
    },
  ),
  routes: {
    ["/home"]: (_) => HomePage(),
    ["/settings"]: (_) => SettingsPage(),
    ["/explore"]: (_) => ExplorePage(),
  },
);

🔑 精确匹配 vs 部分匹配

每个路由可以配置为精确匹配或部分匹配。默认情况下,flyRoute 会根据路径末尾是否有斜杠 / 进行推断:

  • 无斜杠路径被认为是精确匹配:
["details"]: (_) => Details(), // 仅匹配 `/details`
  • 有斜杠路径被认为是部分匹配:
["details/"]: (_) => Details(), // 匹配 `/details/`, `/details/12`, `/details/id=12&foo=99` 等

如果定义了多个路径,则只考虑路径列表中的第一个条目进行默认行为:

["details", "/"]: (_) => Details(), // 仅匹配 `/details` 或 `/` 精确值

如果您想禁用此默认行为,可以使用 RouteConfig 包裹视图:

[ "/admin" ]: (_) => RouteConfig(
  maintainState: false, // 告诉该路由不维护状态
  exactMatch: false, // 告诉该路由不需要精确匹配(可以作为前缀匹配)
  onBeforeEnter: (newRoute) => isLoggedIn == true, // 返回 false 以阻止路径更改
  child: AdminPage(),
)

🎁 参数传递

您可以使用路径参数或查询字符串参数向路由传递参数。

路径参数示例:

flyRoute(
  path: "details/10/20",
  routes: {
    ["details/:foo/:bar"]: (stack) => DetailsPage(
      foo: stack.args["foo"],
      bar: stack.args["bar"],
    ),
  },
)

查询字符串参数示例:

flyRoute(
  path: "/details?foo=10&bar=20",
  routes: {
    ["details/"]: (stack) => DetailsPage(
      foo: stack.args["foo"],
      bar: stack.args["bar"],
    ),
  },
)

📋 完整示例

以下是一个完整的示例,展示了 flyRoute 的大部分功能:

return flyRoute(
  // 当前路径
  path: currentPath,
  // 提供自定义未知路径的页面
  unknownPathBuilder: (_) => Center(child: Text("Custom 404 Page")),
  // 提供自定义的过渡动画
  transitionBuilder: (_, stack, anim1) => FadeTransition(
    opacity: anim1,
    child: stack,
  ),
  // 动画持续时间
  transitionDuration: Duration(milliseconds: 200),
  // 默认页面大小写不敏感,但可以关闭
  caseSensitive: true,
  // 定义所有匹配的路由
  routes: {
    ["home", "/"]: (_) => HomePage(), // 匹配 `/home` 或 `/`
    // 路由守卫示例,返回 false 可阻止更改
    ["admin"]: (_) => RouteConfig(
      child: AdminPage(),
      onBeforeEnter: (_) {
        if (isLoggedIn) return true;
        scheduleMicrotask(() => setState(() => currentPath = "home"));
        return false;
      },
    ),
    // 在路径末尾添加 `/` 表示它可以作为前缀匹配,但可以覆盖此行为
    ["settings/"]: (_) => PflyRoute(
      // 包裹所有设置路由在一个共享的框架中
      scaffoldBuilder: (_, stack) => Column(
        children: [
          Padding(
            padding: EdgeInsets.all(20),
            child: Text("Shared Settings App Bar"), // 设置头部
          ),
          Expanded(child: stack),
        ],
      ),
      // 定义设置部分的子路由
      routes: {
        // 添加空别名,第一个路由将匹配 `/settings/alerts` 和 `/settings/`
        ["alerts", ""]: (_) => AlertsPage(),
        ["profile"]: (_) => ProfilePage(),
        ["billing/:foo/:bar"]: (stack) => BillingPage(
          id: "${stack.args["foo"]}_${stack.args["bar"]}",
        ),
      },
    ),
  },
);
1 回复

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


flyroutes 是一个轻量级的 Flutter 路由管理插件,旨在简化 Flutter 应用中的路由管理。它提供了一种声明式的方式来定义和管理路由,使得代码更加清晰和易于维护。以下是如何使用 flyroutes 插件的基本步骤:

1. 添加依赖

首先,你需要在 pubspec.yaml 文件中添加 flyroutes 依赖:

dependencies:
  flutter:
    sdk: flutter
  flyroutes: ^1.0.0  # 请使用最新版本

然后运行 flutter pub get 来安装依赖。

2. 定义路由

flyroutes 中,你可以通过声明式的方式来定义路由。通常,你可以在 main.dart 文件中定义路由:

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

void main() {
  final routes = FlyRoutes(
    routes: {
      '/': (context) => HomeScreen(),
      '/details': (context) => DetailsScreen(),
      '/profile': (context) => ProfileScreen(),
    },
  );

  runApp(MyApp(routes: routes));
}

class MyApp extends StatelessWidget {
  final FlyRoutes routes;

  MyApp({required this.routes});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'FlyRoutes Example',
      onGenerateRoute: routes.onGenerateRoute,
      initialRoute: '/',
    );
  }
}

3. 导航到其他页面

你可以使用 Navigator.pushNamed 方法来导航到其他页面:

Navigator.pushNamed(context, '/details');

4. 传递参数

flyroutes 支持通过路由传递参数。你可以在定义路由时指定参数,并在导航时传递它们:

final routes = FlyRoutes(
  routes: {
    '/details': (context) {
      final args = ModalRoute.of(context)!.settings.arguments as Map<String, dynamic>;
      return DetailsScreen(data: args['data']);
    },
  },
);

// 导航时传递参数
Navigator.pushNamed(
  context,
  '/details',
  arguments: {'data': 'Some data'},
);

5. 嵌套路由

flyroutes 也支持嵌套路由。你可以在一个页面中定义子路由:

final routes = FlyRoutes(
  routes: {
    '/': (context) => HomeScreen(),
    '/profile': (context) => ProfileScreen(
      childRoutes: FlyRoutes(
        routes: {
          '/profile/settings': (context) => SettingsScreen(),
          '/profile/edit': (context) => EditProfileScreen(),
        },
      ),
    ),
  },
);

6. 自定义路由过渡动画

flyroutes 允许你自定义路由过渡动画。你可以在定义路由时指定 transition 参数:

final routes = FlyRoutes(
  routes: {
    '/details': (context) => DetailsScreen(),
  },
  transition: (context, animation, secondaryAnimation, child) {
    return SlideTransition(
      position: Tween<Offset>(
        begin: const Offset(1.0, 0.0),
        end: Offset.zero,
      ).animate(animation),
      child: child,
    );
  },
);

7. 处理未知路由

你可以通过 unknownRoute 参数来处理未知路由:

final routes = FlyRoutes(
  routes: {
    '/': (context) => HomeScreen(),
  },
  unknownRoute: (context) => NotFoundScreen(),
);

8. 使用 FlyRoute

flyroutes 还提供了 FlyRoute 类,允许你更灵活地定义路由:

final routes = FlyRoutes(
  routes: {
    '/details': FlyRoute(
      builder: (context) => DetailsScreen(),
      transition: (context, animation, secondaryAnimation, child) {
        return FadeTransition(
          opacity: animation,
          child: child,
        );
      },
    ),
  },
);

9. 使用 FlyRouter

FlyRouterflyroutes 的核心类,你可以直接使用它来管理路由:

final router = FlyRouter(
  routes: {
    '/': (context) => HomeScreen(),
    '/details': (context) => DetailsScreen(),
  },
);

runApp(MyApp(router: router));
回到顶部
AI 助手
你好,我是IT营的 AI 助手
您可以尝试点击下方的快捷入口开启体验!