Flutter路由管理插件routefly的使用
Flutter路由管理插件Routefly的使用
Routefly简介
Routefly是由Flutterando社区创建的基于文件夹的路由管理器,灵感来源于NextJS。它允许你通过在特定目录中组织代码文件来自动创建Flutter应用中的路由。当一个文件被添加到"pages"目录时,它会自动作为一个路由可用。只需要在"lib/app"文件夹内添加适当的文件夹结构。
示例
/lib/app/dashboard/dashboard_page.dart
=>/dashboard
/lib/app/users/users_page.dart
=>/users
/lib/app/users/[id]/user_page.dart
=>/users/2
安装与初始化
1. 添加Routefly包到你的Flutter项目:
flutter pub add routefly
2. 修改你的MaterialApp或CupertinoApp,用MaterialApp.router或CupertinoApp.router替换,并使用Routefly.routerConfig方法配置路由器:
import 'package:routefly/routefly.dart';
import 'my_app.route.dart'; // GENERATED
part 'my_app.g.dart'; // GENERATED
@Main('lib/app')
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp.router(
routerConfig: Routefly.routerConfig(
routes: routes, // GENERATED
),
);
}
}
@Main()
接收一个参数作为Routefly用来查找页面的基础文件夹,默认是lib/app
。
3. 组织你的代码,创建包含*_page.dart
文件的文件夹为每个页面。例如:
.
└── app/
├── product/
│ └── product_page.dart
└── user/
└── user_page.dart
4. 使用以下命令生成路由:
dart run routefly
每次创建新的带有页面的文件夹时运行此命令以再次生成路由。你也可以使用--watch
标志,在向文件夹添加新页面时自动生成路由。
路由分组
在app目录中,嵌套文件夹通常映射到URL路径。然而,你可以标记一个文件夹为Route Group以防止该文件夹被包含在路由的URL路径中。这允许你将路由段和项目文件组织成逻辑组而不影响URL路径结构。可以通过括号包裹文件夹名称来创建路由组:(folderName)
。
例如:
.
└── app/
├── (product)/
└── home/
└── home_page.dart
生成的路径为/home
。
导航
Routefly提供了简单的导航方法:
Routefly.navigate('path')
: 替换整个路由栈为请求的路径。Routefly.pushNavigate('path')
: 在现有栈上添加一条新路由。Routefly.push('path')
: 向路由栈添加一条路由。Routefly.pop()
: 移除路由栈顶部的路由。Routefly.replace('path')
: 将最后一个路由替换为请求的路径。
你还可以使用相对路径。
动态路由
动态路由允许从动态数据创建路由。你可以使用方括号内的动态段,如[id]
或[slugs]
。例如,创建一个使用动态段的页面:lib/app/users/[id]/user_page.dart
。这将生成路由路径/users/[id]
。
使用导航命令替换动态段,如Routefly.push('/users/2')
。
访问页面上的动态参数(id)使用Routefly.query['id']
。
你也可以使用Routefly.query.params
访问段参数,例如Routefly.query.params['search']
用于/product?search=Text
。
自定义过渡
要创建自定义路由过渡,可以在页面文件中定义routeBuilder
函数。这允许你基于PageRouteBuilder
使用自定义过渡。例如:
Route routeBuilder(BuildContext context, RouteSettings settings) {
return PageRouteBuilder(
settings: settings,
pageBuilder: (_, a1, a2) => const UserPage(),
transitionsBuilder: (_, a1, a2, child) {
return FadeTransition(opacity: a1, child: child);
},
);
}
你也可以改变全局路由过渡:
return CupertinoApp.router(
routerConfig: Routefly.routerConfig(
routes: routes,
routeBuilder: (context, settings, child) {
return CupertinoPageRoute(
settings: settings,
builder: (context) => child,
);
},
),
);
布局(RouterOutlet)
布局是支持嵌套路由的页面。所有子路由到布局将作为子节点出现在导航中。要创建布局,创建属于它的文件夹并添加*_layout.dart
文件。子文件夹必须位于布局父文件夹内。在布局Widget中添加RouterOutlet()
,指定嵌套路由出现的位置。
例如:
class DashboardLayout extends StatelessWidget {
const DashboardLayout({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Column(
children: [
ListTile(
title: const Text('Option 1'),
onTap: () {
Routefly.navigate(routePaths.dashboard.products);
},
),
ListTile(
title: const Text('Option 2'),
onTap: () {
Routefly.navigate(routePaths.dashboard.users);
},
),
const Expanded(child: RouterOutlet()),
],
),
),
);
}
}
中间件
中间件是拦截请求的函数,可以更改路由信息,取消或重定向路由请求。例如:
FutureOr<RouteInformation> _guardRoute(RouteInformation routeInformation) {
if (routeInformation.uri.path == '/guarded') {
return routeInformation.redirect(Uri.parse('/'));
}
return routeInformation;
}
return MaterialApp.router(
routerConfig: Routefly.routerConfig(
routes: routes,
middlewares: [_guardRoute],
),
);
404页面
创建名为404
的路由,当页面未找到时触发。你可以修改默认的未找到页面路由:
return MaterialApp.router(
routerConfig: Routefly.routerConfig(
routes: routes,
notFoundPath: '/not-found',
),
);
如果你有任何问题或需要帮助,请随时联系Flutterando社区。
快乐路由使用Routefly!
完整示例Demo
下面是一个完整的示例demo,展示了如何使用Routefly进行路由管理:
// file: my_app.dart
import 'package:flutter/material.dart';
import 'package:routefly/routefly.dart';
import 'my_app.route.dart'; // GENERATED
part 'my_app.g.dart'; // GENERATED
@Main('lib/app')
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp.router(
routerConfig: Routefly.routerConfig(
routes: routes, // GENERATED
),
);
}
}
// file: lib/app/home/home_page.dart
import 'package:flutter/material.dart';
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Home')),
body: Center(
child: Text('Welcome to Home Page'),
),
);
}
}
// file: lib/app/product/product_page.dart
import 'package:flutter/material.dart';
class ProductPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Product')),
body: Center(
child: Text('Welcome to Product Page'),
),
);
}
}
// file: lib/app/user/user_page.dart
import 'package:flutter/material.dart';
class UserPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('User')),
body: Center(
child: Text('Welcome to User Page'),
),
);
}
}
// Generate routes using the following command:
// dart run routefly --watch
这个示例展示了如何设置Routefly并创建基本页面。你可以根据需要添加更多页面和功能。
更多关于Flutter路由管理插件routefly的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter路由管理插件routefly的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是如何在Flutter项目中使用routefly
插件进行路由管理的示例代码。routefly
是一个轻量级的路由管理库,它提供了灵活且易于使用的路由管理功能。
1. 添加依赖
首先,你需要在pubspec.yaml
文件中添加routefly
依赖:
dependencies:
flutter:
sdk: flutter
routefly: ^最新版本号 # 请替换为当前最新版本号
然后运行flutter pub get
来安装依赖。
2. 配置路由
接下来,在你的Flutter应用中配置路由。通常,你会在应用的入口文件(例如main.dart
)中进行配置。
import 'package:flutter/material.dart';
import 'package:routefly/routefly.dart';
import 'package:your_app/screens/home_screen.dart';
import 'package:your_app/screens/details_screen.dart';
void main() {
// 初始化路由表
final routes = <String, WidgetBuilder>{
'/': (context) => HomeScreen(),
'/details': (context) => DetailsScreen(),
};
// 使用RouteFly进行路由管理
runApp(
MaterialApp.router(
routeInformationParser: RouteFlyParser(routes.keys.toList()),
routerDelegate: RouteFlyDelegate(
routes: routes,
),
),
);
}
3. 创建屏幕
创建一些示例屏幕,比如HomeScreen
和DetailsScreen
。
home_screen.dart
import 'package:flutter/material.dart';
class HomeScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Home Screen'),
),
body: Center(
child: ElevatedButton(
onPressed: () {
// 导航到详情屏幕
Navigator.pushNamed(context, '/details');
},
child: Text('Go to Details'),
),
),
);
}
}
details_screen.dart
import 'package:flutter/material.dart';
class DetailsScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Details Screen'),
),
body: Center(
child: Text('This is the details screen.'),
),
);
}
}
4. 使用路由参数
你也可以传递路由参数。例如,在HomeScreen
中传递一个参数到DetailsScreen
。
修改HomeScreen
import 'package:flutter/material.dart';
class HomeScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Home Screen'),
),
body: Center(
child: ElevatedButton(
onPressed: () {
// 导航到详情屏幕并传递参数
Navigator.pushNamed(
context,
'/details',
arguments: {'itemId': 123}, // 传递参数
);
},
child: Text('Go to Details'),
),
),
);
}
}
修改DetailsScreen
import 'package:flutter/material.dart';
class DetailsScreen extends StatelessWidget {
final Map<String, dynamic> arguments;
DetailsScreen({required this.arguments});
@override
Widget build(BuildContext context) {
final itemId = arguments['itemId'] ?? 0; // 获取传递的参数
return Scaffold(
appBar: AppBar(
title: Text('Details Screen'),
),
body: Center(
child: Text('Item ID: $itemId'),
),
);
}
}
修改路由配置
你需要确保路由配置能够处理带参数的路由。由于routefly
使用MaterialApp.router
,它默认不支持直接传递参数给构造函数。但你可以使用RouteFlyDelegate
的onGenerateRoute
方法来处理这种情况:
void main() {
final routes = <String, WidgetBuilder>{
'/': (context) => HomeScreen(),
// 不再直接在这里创建DetailsScreen实例
'/details': null,
};
runApp(
MaterialApp.router(
routeInformationParser: RouteFlyParser(routes.keys.toList()),
routerDelegate: RouteFlyDelegate(
routes: routes,
onGenerateRoute: (settings) {
if (settings.name == '/details') {
final args = settings.arguments as Map<String, dynamic>?? {};
return MaterialPageRoute<void>(
settings: settings,
builder: (context) => DetailsScreen(arguments: args),
);
}
return null;
},
),
),
);
}
这样,你就完成了一个基本的Flutter应用,使用routefly
进行路由管理,并传递路由参数。这个示例展示了如何配置路由、创建屏幕以及传递和使用路由参数。