如何查看当前路线是哪条?

Mar*_*rko 20 dart flutter

我想使用抽屉导航到不同的路线,但是如果我已经在该路线上,我每次点击它时都不想打开路线的新实例,而是我希望在这种情况下新的路线是没开.到目前为止这是我的代码:

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)

  • 避免空指针异常的更好方法:`ModalRoute.of(context)?.settings?.name` (19认同)
  • 出于某种原因,Rémi Rousselet 的方法对我有用,但这个方法总是为空。 (2认同)

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)

  • route.settings.name 始终为 null (2认同)

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)


jon*_*ges 8

你可以只使用一个:

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。

好吧,回答这个问题有点晚了,但我希望你和其他阅读这篇文章的用户喜欢

  • 请附上[有关您与该项目的联系的信息](https://stackoverflow.com/help/promotion)。 (5认同)

jur*_*rdb 6

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)

  • 仅仅在移动应用程序中切换页面看起来有点疯狂...... (2认同)

小智 5

ModalRoute.of(context).settings.name
Run Code Online (Sandbox Code Playgroud)

是一个很好的 API 来解决这个问题,但它不能在 initState() 中使用;