我想使用抽屉导航到不同的路线,但是如果我已经在该路线上,我每次点击它时都不想打开路线的新实例,而是我希望在这种情况下新的路线是没开.到目前为止这是我的代码:
Widget build(BuildContext context){
return new Drawer(
child:
new ListView(
children: <Widget>[
new ListTile(
title: new Text("NewRoute"),
onTap: () {
Navigator.of(context).pop;
Navigator.of(context).pushNamed('/NewRoute');
}
)
)
)
}
Run Code Online (Sandbox Code Playgroud)
我想使用条件语句来检查我们是否在某条路线上.我知道有一种方法可以检查我们当前使用Route类的isCurrent的路径
https://docs.flutter.io/flutter/widgets/Route/isCurrent.html
虽然我不知道如何实现它.
先感谢您!
ikb*_*ben 25
这应该给你确切的路线名称
import 'package:path/path.dart';
ModalRoute.of(context).settings.name
Run Code Online (Sandbox Code Playgroud)
为避免空异常,请执行此操作
var route = ModalRoute.of(context);
if(route!=null){
print(route.settings.name);
}
Run Code Online (Sandbox Code Playgroud)
jgl*_*tre 12
这是 Dart 扩展方法的完美用例(基于 Rémi Rousselet 的回答):
extension NavigatorStateExtension on NavigatorState {
void pushNamedIfNotCurrent( String routeName, {Object arguments} ) {
if (!isCurrent(routeName)) {
pushNamed( routeName, arguments: arguments );
}
}
bool isCurrent( String routeName ) {
bool isCurrent = false;
popUntil( (route) {
if (route.settings.name == routeName) {
isCurrent = true;
}
return true;
} );
return isCurrent;
}
}
Run Code Online (Sandbox Code Playgroud)
然后它看起来像这样干净:
Navigator.of(context).pushNamedIfNotCurrent('/NewRoute');
Run Code Online (Sandbox Code Playgroud)
Rém*_*let 11
Navigator 不暴露当前路线.
你可以做的是Navigator.popUntil(callback)用作popUtil回传当前的回调Route,包括它的名字和东西.
final newRouteName = "/NewRoute";
bool isNewRouteSameAsCurrent = false;
Navigator.popUntil(context, (route) {
if (route.settings.name == newRouteName) {
isNewRouteSameAsCurrent = true;
}
return true;
});
if (!isNewRouteSameAsCurrent) {
Navigator.pushNamed(context, newRouteName);
}
Run Code Online (Sandbox Code Playgroud)
你可以只使用一个:
Get.currentRoute
Run Code Online (Sandbox Code Playgroud)
使用这个包:https : //pub.dev/packages/get
你会有当前的路线。
但是你不需要这个,因为与标准 Flutter 不同,Get 可以防止用户意外点击按钮两次(如果用户使用的是低成本设备,它会在卡顿后发生)。然后你只需要使用:Get.to(Home());准备好,就可以了!
目前,由于这个原因,Getx 对于使用 Flutter 的项目几乎是必不可少的。我查看了所有问题,它们很酷,但它们通常涉及使用 popUntil 来访问路由,当其他开发人员阅读您的代码时,这似乎是一种黑客攻击。使用 GetX,您将不会遇到这种双击问题,因为如果您使用 Get.to(Page(), preventDuplicates: false); 明确禁用它,它只会导航到相同的另一个页面;请记住,这是例外情况,在您的情况下,您可以简单地使用:Get.to(Page()); 并导航到下一页而没有任何重复路线的风险,因为防止这种事情已经成为标准。
获取当前路由似乎也涉及很多样板文件,使用 Get 你可以获得当前路由的名称(即使你没有命名路由它也会给你它的名称),使用一个简单的:Get.currenteRoute。
好吧,回答这个问题有点晚了,但我希望你和其他阅读这篇文章的用户喜欢
Rémi的回答确实对我有所帮助,但是如果您像我一样是Flutter / Dart的新手,那么需要一段时间才能理解。因此,这是我的版本,其中包含一些额外的检查和解释性文档:
/// Navigates through the application. Only replaces the top Route if it is
/// different from the new Route. Always keeps the home page as base of the
/// Navigator stack. New screens are pushed on the Navigator stack. When the
/// user switches between non-home screens, the new screen replaces the old
/// screen. In this way, the stack of screens from the drawer is never higher
/// than 2. Returning to the HomeScreen is done by just popping the current
/// Route.
void _changeRoute(BuildContext context, String newRouteName) {
// Close drawer
Navigator.pop(context);
// Check current screen status
bool currentRouteIsHome = false;
bool currentRouteIsNewRoute = false;
Navigator.popUntil(context, (currentRoute) {
// This is just a way to access currentRoute; the top route in the
// Navigator stack.
if (currentRoute.settings.name == HomeScreen.ROUTE_NAME) {
currentRouteIsHome = true;
}
if (currentRoute.settings.name == newRouteName) {
currentRouteIsNewRoute = true;
}
// Return true so popUntil() pops nothing.
return true;
});
// Switch screen
if (!currentRouteIsNewRoute) {
// Only switch screen if new route is different from current route.
if (currentRouteIsHome) {
// Navigate from home to non-home screen.
Navigator.pushNamed(context, newRouteName);
} else {
if (newRouteName == HomeScreen.ROUTE_NAME) {
// Navigate from non-home screen to home.
Navigator.pop(context);
} else {
// Navigate from non-home screen to non-home screen.
Navigator.popAndPushNamed(context, newRouteName);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,使用pushNamed和实现popAndPushNamed需要您在参数的Route顶级中定义名称,如下所示:MaterialApproutes:
new MaterialApp(
routes: <String, WidgetBuilder>{
// define the routes
YOUR_SCREEN_ROUTE_NAME: (BuildContext context) => new YourScreen(),
},
)
Run Code Online (Sandbox Code Playgroud)
小智 5
ModalRoute.of(context).settings.name
Run Code Online (Sandbox Code Playgroud)
是一个很好的 API 来解决这个问题,但它不能在 initState() 中使用;
| 归档时间: |
|
| 查看次数: |
8861 次 |
| 最近记录: |