ModalRoute应该给你准确的路由名称
ModalRoute.of(context).settings.name
如果您想通过使用导航键获取当前路由,则可以使用popUntil方法:
String? currentPath;
navigatorKey.currentState?.popUntil((route) {
currentPath = route.settings.name;
return true;
});
NavigatorState
没有提供API来获取当前路由的路径,Route
也没有提供确定路由路径的API。路由可以是匿名的(通常如此)。您可以使用isCurrent
方法确定给定的Route
是否在导航器堆栈的顶部,但这对于您的用例不是很方便。我建议您采用不同的方法来解决这个问题,根本不需要回到根路径。相反,为BottomNavigationBar
的每个窗格使用不同的Navigator
小部件。这样,当在窗格之间切换时,您就不必倒回堆栈。您可以将Navigator
小部件包装在Opacity
和IgnorePointer
小部件中,在不破坏它们的堆栈的情况下隐藏它们。
import 'package:flutter/material.dart';
void main() {
runApp(new MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
home: new MyHomePage(),
);
}
}
class SecurePage extends StatelessWidget {
final int index;
SecurePage(this.index);
Widget build(BuildContext context) {
return new Material(
color: Colors.amber,
child: new InkWell(
child: new Center(
child: new Icon(
Icons.security,
color: Colors.white,
size: index * 100.0 + 20.0,
),
),
onTap: () {
Navigator.of(context).push(
new MaterialPageRoute(
builder: (BuildContext context) {
return new SecurePage(index + 1);
},
),
);
},
),
);
}
}
class VerifiedPage extends StatelessWidget {
final int index;
VerifiedPage(this.index);
Widget build(BuildContext context) {
return new Material(
color: Colors.green,
child: new InkWell(
child: new Center(
child: new Icon(
Icons.verified_user,
color: Colors.white,
size: index * 100.0 + 20.0,
),
),
onTap: () {
Navigator.of(context).push(
new MaterialPageRoute(
builder: (BuildContext context) {
return new VerifiedPage(index + 1);
},
),
);
},
),
);
}
}
class MyHomePage extends StatefulWidget {
@override
State createState() => new MyHomePageState();
}
class MyHomePageState extends State<MyHomePage> {
int _page = 0;
List<Widget> initialWidgets = <Widget>[
new SecurePage(0),
new VerifiedPage(0),
];
Widget build(BuildContext context) {
return new Scaffold(
body: new Stack(
children: new List<Widget>.generate(initialWidgets.length, (int index) {
return new IgnorePointer(
ignoring: index != _page,
child: new Opacity(
opacity: _page == index ? 1.0 : 0.0,
child: new Navigator(
onGenerateRoute: (RouteSettings settings) {
return new MaterialPageRoute(
builder: (_) => initialWidgets[index],
);
},
),
),
);
}),
),
bottomNavigationBar: new BottomNavigationBar(
currentIndex: _page,
onTap: (int index) {
setState(() {
_page = index;
});
},
items: <BottomNavigationBarItem>[
new BottomNavigationBarItem(
icon: new Icon(Icons.security),
title: new Text('Secure'),
),
new BottomNavigationBarItem(
icon: new Icon(Icons.verified_user),
title: new Text('Verified'),
),
],
),
);
}
}
GoRouter.of(context).location
GoRouterState.of(context).uri.toString();
final currentPath = GoRouter.of(navigatorKey.currentContext!).location;
- Till Friebeuri.toString()
和routeInformationProvider.value.location
有什么区别? - Kyle Venn我发布这个答案主要是为了存档,但正如@ikben提到的,获取当前路由及其所有属性的一种方法是ModalRoute.of(context)
。它返回一个ModalRoute
,尽管名称中带有 "Modal",但适用于大多数Navigator.push
调用,而不仅仅是showDialog
。有用的属性包括Route.settings
、Route.navigator
和Route.isFirst
。
GoRouter.of(context).routeInformationProvider.value.location
或者
GoRouterState.of(context).location
我在我的项目中使用go_router。在go_router中,您可以如下访问当前路由:
var currentRoute = GoRouter.of(context).location;
我也遇到了这个问题,当时我正在使用onGenerateRoute。后来我通过使用NavigatorObserver解决了这个问题。
import 'package:flutter/material.dart';
class AppNavObserver extends NavigatorObserver {
static final navStack = <RouteStackItem>[];
@override
void didPop(Route route, Route? previousRoute) {
if (previousRoute != null) {
navStack.removeLast();
}
super.didPop(route, previousRoute);
}
@override
void didPush(Route route, Route? previousRoute) {
navStack.add(RouteStackItem.fromRoute(route));
super.didPush(route, previousRoute);
}
@override
void didRemove(Route route, Route? previousRoute) {
if (previousRoute != null) {
navStack.removeLast();
}
super.didRemove(route, previousRoute);
}
@override
void didReplace({Route? newRoute, Route? oldRoute}) {
if (oldRoute != null) {
navStack.removeLast();
}
if (newRoute != null) {
navStack.add(RouteStackItem.fromRoute(newRoute));
}
super.didReplace(newRoute: newRoute, oldRoute: oldRoute);
}
@override
void didStartUserGesture(Route route, Route? previousRoute) {
// TODO: implement didStartUserGesture
super.didStartUserGesture(route, previousRoute);
}
@override
void didStopUserGesture() {
// TODO: implement didStopUserGesture
super.didStopUserGesture();
}
}
class RouteStackItem {
final String? name;
final Object? args;
const RouteStackItem({
required this.name,
required this.args,
});
factory RouteStackItem.fromRoute(Route route) =>
RouteStackItem(name: route.settings.name, args: route.settings.arguments);
}
MaterialApp(
debugShowCheckedModeBanner: false,
title: flavorConfig.appTitle,
color: AppColors.primary,
theme: AppTheme.light,
navigatorObservers: [
AppNavObserver()
],.....
var navStack = AppNavObserver.navStack;
var routeSettings = navStack.isEmpty ? null : navStack.last;
go_router
:GoRoute(
name: 'login',
path: '/login',
builder: (context, state) => LoginScreen(),
),
GoRouterState.of(context).path
使用命名路由:
GoRouterState.of(context).name
class NavListTile extends StatelessWidget {
static String currentRoute = 'dashboard';
final String route;
const NavListTile({
Key? key,
required this.route,
}) : super(key: key);
@override
Widget build(BuildContext context) {
var isCurrent = currentRoute == route;
String suffix = isCurrent ? '_green' : '';
return ListTile(
title: NavMenuItem(capitalizedRoute, isCurrent,
"assets/images/" + route + suffix + ".png", context),
onTap: () {
currentRoute = route;
Navigator.of(context).pushNamed('/' + route);
},
);
}
}