Flutter增强路由管理插件go_router_plus的使用
Flutter增强路由管理插件 go_router_plus
的使用
Go Router Plus
是一个增强版的路由管理插件,基于 go_router
,旨在解决大型应用中复杂的路由管理和重定向逻辑。本文将详细介绍如何使用 go_router_plus
来构建和管理路由。
安装
首先,通过以下命令安装 go_router_plus
:
flutter pub add go_router_plus
安装完成后,可以在 Dart 文件中导入该包:
import 'package:go_router_plus/go_router_plus.dart';
创建屏幕(Screens)
在 go_router_plus
中,每个屏幕都需要继承自 Screen
类,并实现一些必要的方法和属性。
示例:创建第一个屏幕
// lib/screens/my_first_screen.dart
import 'package:go_router_plus/go_router_plus.dart';
import 'package:flutter/material.dart';
class MyFirstScreen extends Screen {
[@override](/user/override)
Widget build(BuildContext context, GoRouterState state) {
return const Text('Hello world');
}
[@override](/user/override)
String get routeName => 'my_first_screen';
[@override](/user/override)
String get routePath => '/my-first-screen';
}
必须实现的方法和属性:
build(BuildContext context, GoRouterState state)
:返回Widget
或Page<void>
,通常情况下返回Widget
。routeName
:唯一标识该屏幕的名称。routePath
:该屏幕对应的路径。
标记初始屏幕
如果要设置初始屏幕,可以通过实现 InitialScreen
接口来标记某个屏幕为初始屏幕:
class LoginScreen extends Screen implements InitialScreen {
[@override](/user/override)
Widget build(BuildContext context, GoRouterState state) {
return const Text('Login screen');
}
[@override](/user/override)
String get routeName => 'login';
[@override](/user/override)
String get routePath => '/login';
}
标记错误屏幕
当遇到路由错误时,可以使用 ErrorScreen
接口来定义一个错误页面:
class MyErrorScreen extends Screen implements ErrorScreen {
[@override](/user/override)
Widget build(BuildContext context, GoRouterState state) {
return Text(state.error.toString());
}
[@override](/user/override)
String get routeName => 'error';
[@override](/user/override)
String get routePath => '/error';
}
嵌套路由(Nested Navigation)
ShellRoute
提供了嵌套路由的支持,允许你将多个子路由包裹在一个 UI Shell 中。你可以通过继承 ShellScreen
来实现嵌套路由:
class MyShellScreen extends ShellScreen {
[@override](/user/override)
List<ScreenBase> subScreens() {
return [
ScreenA(),
ScreenB(),
];
}
}
创建路由
使用 createGoRouter
工厂函数来创建路由配置:
final router = createGoRouter(
screens: [
LoginScreen(),
MyFirstScreen(),
MyErrorScreen(),
],
);
重定向器(Redirectors)
Redirector
负责处理所有路由的重定向逻辑。你可以通过 redirectors
参数传递多个重定向器。
认证重定向
AuthRedirector
提供了一个内置的认证重定向功能,帮助你根据用户登录状态进行重定向。
示例:实现认证重定向
class AuthService with ChangeNotifier implements LoggedInState {
bool _loggedIn = false;
[@override](/user/override)
bool get loggedIn => _loggedIn;
void login() {
_loggedIn = true;
notifyListeners();
}
void logout() {
_loggedIn = false;
notifyListeners();
}
}
class LoginScreen extends Screen implements GuestScreen {
[@override](/user/override)
String get routePath => '/login';
[@override](/user/override)
Widget build(BuildContext context, GoRouterState state) {
return Scaffold(
body: const Text('Login screen'),
floatingActionButton: FloatingActionButton(
onPressed: () => AuthService().login(),
child: const Icon(Icons.login),
),
);
}
}
class HomeScreen extends Screen implements UserScreen {
[@override](/user/override)
String get routePath => '/home';
[@override](/user/override)
Widget build(BuildContext context, GoRouterState state) {
return Scaffold(
body: const Text('Home screen'),
floatingActionButton: FloatingActionButton(
onPressed: () => AuthService().logout(),
child: const Icon(Icons.logout),
),
);
}
}
final authService = AuthService();
final router = createGoRouter(
screens: [
LoginScreen(),
HomeScreen(),
],
redirectors: [
AuthRedirector(
state: authService,
guestRedirectPath: '/login',
userRedirectPath: '/home',
),
],
);
屏幕重定向
如果你需要为某些屏幕实现自定义的重定向逻辑,可以实现 RedirectAware
接口:
class VipScreen extends Screen implements UserScreen, RedirectAware {
[@override](/user/override)
FutureOr<String?> redirect(BuildContext context, GoRouterState state) {
// 检查当前用户是否是 VIP
final currentUser = ...; // 获取当前用户信息
return !currentUser.isVip ? '/home' : null;
}
[@override](/user/override)
Widget build(BuildContext context, GoRouterState state) {
return const Text('VIP Screen');
}
[@override](/user/override)
String get routePath => '/vip';
}
然后在创建路由时添加 ScreenRedirector
:
final router = createGoRouter(
screens: [
LoginScreen(),
HomeScreen(),
VipScreen(),
],
redirectors: [
ScreenRedirector(),
AuthRedirector(
state: authService,
guestRedirectPath: '/login',
userRedirectPath: '/home',
),
],
);
刷新监听器(Refresh Notifiers)
go_router_plus
允许你添加多个刷新监听器,以便在某些状态变化时重新触发重定向逻辑。
示例:添加刷新监听器
class PromotionService with ChangeNotifier {
void activate() {
notifyListeners();
}
}
final authService = AuthService();
final promotionService = PromotionService();
final router = createGoRouter(
screens: [
ManageUserScreen(),
],
redirectors: [
AuthRedirector(
state: authService,
guestRedirectPath: '/login',
userRedirectPath: '/home',
),
],
refreshNotifiers: [
authService,
promotionService,
],
);
完整示例 Demo
以下是一个完整的示例代码,展示了如何使用 go_router_plus
构建一个简单的登录和主页应用:
import 'package:flutter/material.dart';
import 'package:go_router_plus/go_router_plus.dart';
void main() {
final authService = AuthService();
final router = createGoRouter(
screens: [
LoginScreen(authService),
HomeScreen(authService),
],
redirectors: [
AuthRedirector(
state: authService,
guestRedirectPath: '/login',
userRedirectPath: '/home',
),
],
refreshNotifiers: [
authService,
],
);
runApp(
MaterialApp.router(
routeInformationParser: router.routeInformationParser,
routerDelegate: router.routerDelegate,
routeInformationProvider: router.routeInformationProvider,
),
);
}
class LoginScreen extends Screen implements InitialScreen, GuestScreen {
LoginScreen(this.authService);
final AuthService authService;
[@override](/user/override)
Widget build(BuildContext context, GoRouterState state) {
return Scaffold(
body: const Center(child: Text('Login screen')),
floatingActionButton: FloatingActionButton(
onPressed: authService.login,
child: const Icon(Icons.login),
),
);
}
[@override](/user/override)
String get routeName => 'login';
[@override](/user/override)
String get routePath => '/login';
}
class HomeScreen extends Screen implements UserScreen {
HomeScreen(this.authService);
final AuthService authService;
[@override](/user/override)
Widget build(BuildContext context, GoRouterState state) {
return Scaffold(
body: const Center(child: Text('Home screen')),
floatingActionButton: FloatingActionButton(
onPressed: authService.logout,
child: const Icon(Icons.logout),
),
);
}
[@override](/user/override)
String get routeName => 'home';
[@override](/user/override)
String get routePath => '/home';
}
class AuthService with ChangeNotifier implements LoggedInState {
bool _loggedIn = false;
[@override](/user/override)
bool get loggedIn => _loggedIn;
void login() {
_loggedIn = true;
notifyListeners();
}
void logout() {
_loggedIn = false;
notifyListeners();
}
}
更多关于Flutter增强路由管理插件go_router_plus的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter增强路由管理插件go_router_plus的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是一个关于如何在Flutter项目中使用go_router_plus
插件来增强路由管理的代码示例。go_router_plus
是一个扩展自go_router
的插件,提供了更多高级功能,比如嵌套导航、全局守卫等。
首先,确保你已经在pubspec.yaml
文件中添加了go_router_plus
依赖:
dependencies:
flutter:
sdk: flutter
go_router: ^5.0.0 # 请注意版本号,确保与go_router_plus兼容
go_router_plus: ^x.y.z # 替换为最新版本号
然后,运行flutter pub get
来安装依赖。
接下来是一个简单的示例,展示如何使用go_router_plus
进行路由管理:
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:go_router_plus/go_router_plus.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
final GoRouterPlus _goRouterPlus = GoRouterPlus(
routes: [
GoRoute(
path: '/',
builder: (context, state) => HomeScreen(),
routes: [
GoRoute(
path: 'details/:id',
builder: (context, state) {
final id = state.params['id']!;
return DetailsScreen(id: id);
},
),
],
),
],
navigatorBuilders: <Type, NavigatorBuilder>{
MaterialNavigator: (navigatorKey, router, builder) {
return MaterialApp.router(
key: navigatorKey,
router: router,
builder: builder,
title: 'GoRouterPlus Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
);
},
},
errorPageBuilder: (context, state) {
// 自定义错误页面
return Scaffold(
appBar: AppBar(title: Text('Error')),
body: Center(
child: Text('An error occurred: ${state.error.toString()}'),
),
);
},
redirectingPageBuilder: (context, state) {
// 自定义重定向页面(可选)
return Scaffold(
appBar: AppBar(title: Text('Redirecting')),
body: Center(
child: CircularProgressIndicator(),
),
);
},
);
@override
Widget build(BuildContext context) {
return _goRouterPlus.router.builder(context);
}
}
class HomeScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Home')),
body: Center(
child: ElevatedButton(
onPressed: () {
// 导航到详情页面,传递参数
context.go('/details/123');
},
child: Text('Go to Details'),
),
),
);
}
}
class DetailsScreen extends StatelessWidget {
final String id;
DetailsScreen({required this.id});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Details')),
body: Center(
child: Text('Details for ID: $id'),
),
);
}
}
在这个示例中,我们做了以下几件事:
- 定义路由:使用
GoRouterPlus
定义了一个路由表,其中包含一个根路由/
和一个嵌套路由/details/:id
。 - 导航器构建器:使用
navigatorBuilders
定义了MaterialNavigator
的构建方式,这样可以自定义MaterialApp
的主题和其他属性。 - 错误页面:使用
errorPageBuilder
自定义了一个错误页面,当路由发生错误时会显示这个页面。 - 重定向页面(可选):使用
redirectingPageBuilder
自定义了一个重定向页面,当路由正在进行重定向时会显示这个页面(本例中未实际触发重定向,仅作为示例)。 - 导航:在
HomeScreen
中使用context.go
方法导航到详情页面,并传递了一个参数id
。
这个示例展示了如何使用go_router_plus
进行基本的路由管理和错误处理。根据具体需求,你可以进一步扩展这个示例,比如添加全局守卫、嵌套导航等高级功能。