我有一个
GoRouter
:
GoRouter(
navigatorKey: _rootNavigatorKey,
routes: [
GoRoute(
path: '/login',
),
ShellRoute(
navigatorKey: _shellNavigatorKey,
routes: [
GoRoute(
path: '/dashboard',
),
// ... other routes
]
),
GoRoute(
parentNavigatorKey: _rootNavigatorKey,
path: '/dashboard',
),
// ... other routes
],
)
您可能会注意到,我在不同的地方使用相同的路线
/dashboard
(和类似的路线)。事实上,我可以从 BottomNavigationBar
或 Drawer
重定向到类似的路线。当我从 dashboard
转到 Drawer
时,我需要在 AppBar
上有一个后退按钮,因此我使用 go.push()
将路线放置在 ScaffoldWithNavigation
当前所选路线上方。
问题是是否可以在不同的路线集中使用相同的
GoRoute
(相同的path
)?或者我应该使用不同的路线?
我决定按照 BambinoUA 的要求提供此答案。
以下是演示的相关代码片段:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart';
import 'package:go_router/go_router.dart';
import 'package:flutter/foundation.dart' show kIsWeb;
class GoRouterMobile {
static CustomTransitionPage noTransition(
GoRouterState state,
Widget page,
) {
return CustomTransitionPage(
key: state.pageKey,
child: page,
transitionDuration: Duration.zero,
transitionsBuilder: (context, animation, secondaryAnimation, child) =>
child,
);
}
}
final GlobalKey<NavigatorState> _navigatorKey = GlobalKey<NavigatorState>();
final router = GoRouter(
navigatorKey: _navigatorKey,
initialLocation: '/',
routes: <RouteBase>[
GoRoute(
path: '/',
pageBuilder: (context, state) => GoRouterMobile.noTransition(
state,
Home(),
),
routes: [
GoRoute(
path: 'page1', // for web browser purposes
pageBuilder: (context, state) => GoRouterMobile.noTransition(
state,
Page1(),
),
routes: [
GoRoute(
path: 'page2', // for web browser purposes
pageBuilder: (context, state) => GoRouterMobile.noTransition(
state,
Page2(),
),
),
],
),
],
),
GoRoute(
path: '/page1', // for mobile app purposes
pageBuilder: (context, state) => GoRouterMobile.noTransition(
state,
Page1(),
),
),
GoRoute(
path: '/page2', // for mobile app purposes
pageBuilder: (context, state) => GoRouterMobile.noTransition(
state,
Page2(),
),
),
],
);
class Home extends StatefulWidget {
const Home({super.key});
@override
State<Home> createState() => _HomeState();
}
class _HomeState extends State<Home> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Home'),
),
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text('Home'),
SizedBox(
height: 8,
),
ElevatedButton(
onPressed: () {
kIsWeb
? context.go('///page1')
: GoRouter.of(context).push(Uri(path: '/page1').toString());
},
child: Text('Go to Page 1'),
),
],
),
),
);
}
}
class Page1 extends StatefulWidget {
const Page1({super.key});
@override
State<Page1> createState() => _Page1State();
}
class _Page1State extends State<Page1> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
leading: IconButton(
onPressed: () {
if (GoRouter.of(context).canPop()) {
GoRouter.of(context).pop();
}
},
icon: Icon(CupertinoIcons.chevron_back),
),
title: Text('Page 1'),
),
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text('Page 1'),
SizedBox(
height: 8,
),
ElevatedButton(
onPressed: () {
kIsWeb
? context.go('///page1/page2')
: GoRouter.of(context)
.push(Uri(path: '/page2').toString());
},
child: Text('Go to Page 2'),
),
],
),
),
);
}
}
class Page2 extends StatefulWidget {
const Page2({super.key});
@override
State<Page2> createState() => _Page2State();
}
class _Page2State extends State<Page2> {
@override
Widget build(BuildContext context) {
return KeyboardDismissOnTap(
dismissOnCapturedTaps: true,
child: Scaffold(
appBar: AppBar(
leading: IconButton(
onPressed: () {
if (GoRouter.of(context).canPop()) {
GoRouter.of(context).pop();
}
},
icon: Icon(CupertinoIcons.chevron_back),
),
title: Text('Page 2'),
),
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text('Page 2'),
SizedBox(
height: 8,
),
ElevatedButton(
onPressed: () {
context.go('/'); // to avoid having a page stack in the page cycle
},
child: Text('Go to Home'),
),
],
),
),
),
);
}
}
该代码最初专门用于移动应用程序,但我还决定包含
go_router
实现的 Web 行为。
这是网络运行时:
这是移动运行时:
代码片段解释:从上面的输出中可以看到,
go_route
层次结构引入了不同路由集中的路径。
您可以将其用作导航的参考,对于网络使用
context.go
(但视情况而定),对于移动设备使用 GoRouter.of(context).push
。
希望对你有帮助!