在鸿蒙上使用 go_router_builder Flutter 包
插件介绍
go_router_builder 是一个为 go_router 提供的代码生成器,它通过 Dart 的注解和代码生成功能,帮助开发者构建类型安全的路由系统。这个包的核心价值在于将路由定义、参数解析和导航逻辑进行类型化,从而将运行时错误转化为编译时错误,提高代码质量和开发效率。
主要功能
- 类型安全的路由定义:使用 Dart 类定义路由,确保参数类型正确
- 自动生成导航代码:自动生成
go、push和location等导航方法 - 参数处理自动化:自动处理路径参数、查询参数和额外参数
- 支持复杂路由结构:支持嵌套路由、重定向、ShellRoute 等高级功能
- 类型转换支持:自动处理基本类型和枚举类型的转换
- 自定义过渡动画:支持自定义页面过渡效果
适用场景
- 需要构建复杂路由结构的大型应用
- 希望通过类型安全提高代码质量的项目
- 希望减少路由相关样板代码的开发者
- 需要支持深度链接和 Web 导航的跨平台应用
安装与配置
由于这是一个为鸿蒙平台定制的修改版本,我们需要通过 Git 形式引入依赖。
1. 添加依赖
在项目的 pubspec.yaml 文件中添加以下依赖配置:
dependencies:
flutter:
sdk: flutter
go_router:
git:
url: "https://gitcode.com/openharmony-tpc/flutter_packages.git"
path: "packages/go_router"
go_router_builder:
git:
url: "https://gitcode.com/openharmony-tpc/flutter_packages.git"
path: "packages/go_router_builder"
dev_dependencies:
flutter_test:
sdk: flutter
build_runner:
^2.3.0
2. 配置构建脚本
在项目根目录下创建或修改 build.yaml 文件,添加以下配置:
targets:
$default:
builders:
go_router_builder:
enabled: true
API 调用示例
下面通过一个完整的示例,展示如何在鸿蒙应用中使用 go_router_builder。
1. 定义路由数据类
创建 lib/routes.dart 文件,定义应用的路由结构:
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
// 导入生成的路由代码
part 'routes.g.dart';
// 主路由
<HomeRoute>(
path: '/',
routes: <TypedGoRoute<GoRouteData>>[
TypedGoRoute<FamilyRoute>(
path: 'family/:familyId',
routes: <TypedGoRoute<GoRouteData>>[
TypedGoRoute<PersonRoute>(
path: 'person/:personId',
),
],
),
TypedGoRoute<LoginRoute>(path: '/login'),
TypedGoRoute<SettingsRoute>(path: '/settings'),
],
)
class HomeRoute extends GoRouteData {
const HomeRoute();
Widget build(BuildContext context, GoRouterState state) {
return Scaffold(
appBar: AppBar(title: const Text('Home')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () => const FamilyRoute(familyId: 'f1').go(context),
child: const Text('View Family'),
),
ElevatedButton(
onPressed: () => const LoginRoute(from: '/').go(context),
child: const Text('Login'),
),
ElevatedButton(
onPressed: () => const SettingsRoute().go(context),
child: const Text('Settings'),
),
],
),
),
);
}
}
// 家族路由
class FamilyRoute extends GoRouteData {
const FamilyRoute({required this.familyId});
final String familyId;
Widget build(BuildContext context, GoRouterState state) {
return Scaffold(
appBar: AppBar(title: Text('Family $familyId')),
body: Center(
child: ElevatedButton(
onPressed: () => PersonRoute(familyId: familyId, personId: 'p1').go(context),
child: const Text('View Person'),
),
),
);
}
}
// 人员路由
class PersonRoute extends GoRouteData {
const PersonRoute({required this.familyId, required this.personId});
final String familyId;
final String personId;
Widget build(BuildContext context, GoRouterState state) {
return Scaffold(
appBar: AppBar(title: Text('Person $personId')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Family ID: $familyId'),
Text('Person ID: $personId'),
ElevatedButton(
onPressed: () => context.pop(),
child: const Text('Back'),
),
],
),
),
);
}
}
// 登录路由
class LoginRoute extends GoRouteData {
const LoginRoute({this.from});
final String? from;
Widget build(BuildContext context, GoRouterState state) {
return Scaffold(
appBar: AppBar(title: const Text('Login')),
body: Center(
child: ElevatedButton(
onPressed: () {
// 登录成功后返回原页面或首页
if (from != null) {
context.go(from!);
} else {
const HomeRoute().go(context);
}
},
child: const Text('Login'),
),
),
);
}
}
// 设置路由
class SettingsRoute extends GoRouteData {
const SettingsRoute();
Widget build(BuildContext context, GoRouterState state) {
return Scaffold(
appBar: AppBar(title: const Text('Settings')),
body: const Center(
child: Text('Settings Page'),
),
);
}
}
// 错误路由
class ErrorRoute extends GoRouteData {
const ErrorRoute(this.error);
final Exception error;
Widget build(BuildContext context, GoRouterState state) {
return Scaffold(
appBar: AppBar(title: const Text('Error')),
body: Center(
child: Text('Error: ${error.toString()}'),
),
);
}
}
2. 生成路由代码
运行以下命令生成路由代码:
flutter pub run build_runner build --delete-conflicting-outputs
这将生成 lib/routes.g.dart 文件,包含所有自动生成的路由代码。
3. 配置路由
在应用的入口文件(如 lib/main.dart)中配置路由:
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'routes.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
Widget build(BuildContext context) {
final router = GoRouter(
routes: $appRoutes,
initialLocation: '/',
errorBuilder: (context, state) => ErrorRoute(state.error!).build(context),
);
return MaterialApp.router(
title: 'GoRouter Builder Example',
theme: ThemeData(
primarySwatch: Colors.blue,
),
routerConfig: router,
);
}
}
4. 使用导航功能
现在你可以使用类型安全的方式进行导航:
// 导航到家族页面
FamilyRoute(familyId: 'f1').go(context);
// 导航到人员页面
PersonRoute(familyId: 'f1', personId: 'p1').go(context);
// 带返回值的导航
final result = await PersonRoute(familyId: 'f1', personId: 'p1').push<String>(context);
// 获取路由位置
final location = PersonRoute(familyId: 'f1', personId: 'p1').location;
print(location); // 输出: /family/f1/person/p1
5. 高级功能示例
5.1 重定向
final router = GoRouter(
routes: $appRoutes,
redirect: (state) {
final loggedIn = false; // 实际应用中从状态管理获取
final loggingIn = state.matchedLocation == const LoginRoute().location;
if (!loggedIn && !loggingIn) {
return LoginRoute(from: state.matchedLocation).location;
}
if (loggedIn && loggingIn) {
return const HomeRoute().location;
}
return null;
},
);
5.2 自定义过渡动画
class FancyRoute extends GoRouteData {
const FancyRoute();
Widget build(BuildContext context, GoRouterState state) {
return const Scaffold(
body: Center(
child: Text('Fancy Page'),
),
);
}
MaterialPage<void> buildPage(BuildContext context, GoRouterState state) {
return CustomTransitionPage<void>(
key: state.pageKey,
child: build(context, state),
transitionsBuilder: (context, animation, secondaryAnimation, child) {
return RotationTransition(
turns: animation,
child: child,
);
},
);
}
}
5.3 使用枚举类型
enum BookCategory {
fiction,
nonfiction,
science,
}
<BooksRoute>(path: '/books')
class BooksRoute extends GoRouteData {
const BooksRoute({this.category = BookCategory.fiction});
final BookCategory category;
Widget build(BuildContext context, GoRouterState state) {
return Scaffold(
appBar: AppBar(title: Text('Books - ${category.name}')),
body: Center(
child: Text('Category: ${category.name}'),
),
);
}
}
// 使用方式
BooksRoute(category: BookCategory.science).go(context);
鸿蒙平台注意事项
在鸿蒙平台上使用 go_router_builder 时,需要注意以下几点:
-
深度链接支持:鸿蒙平台对深度链接的支持可能与 Android 略有不同,需要确保在
module.json5文件中正确配置路由规则。 -
性能优化:鸿蒙平台对应用性能有严格要求,建议合理使用路由缓存和懒加载功能。
-
资源管理:在使用复杂路由结构时,注意页面资源的释放,避免内存泄漏。
-
版本兼容性:确保使用与鸿蒙 SDK 兼容的 Flutter 版本和 go_router_builder 版本。
总结
go_router_builder 是一个强大的路由代码生成工具,它通过类型安全的方式帮助开发者构建高质量的路由系统。在鸿蒙平台上使用这个包,可以带来以下好处:
- 提高开发效率:减少路由相关的样板代码,自动生成导航方法
- 增强代码质量:将运行时错误转化为编译时错误,提高应用稳定性
- 支持复杂功能:轻松实现嵌套路由、重定向、ShellRoute 等高级功能
- 跨平台兼容:同时支持鸿蒙、Android、iOS 和 Web 平台
通过本文的介绍和示例,相信你已经对 go_router_builder 在鸿蒙平台上的使用有了全面的了解。这个工具不仅可以提高你的开发效率,还能帮助你构建更加健壮和可维护的应用。
如果你想深入了解更多高级功能,可以查看官方文档和示例项目,进一步探索 go_router_builder 的强大功能。
欢迎加入开源鸿蒙跨平台社区: https://openharmonycrossplatform.csdn.net
更多推荐
所有评论(0)