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 回复