【问题标题】:How to get current route path in Flutter?如何在 Flutter 中获取当前路由路径?
【发布时间】:2018-03-11 01:42:28
【问题描述】:

在实现persistent bottom bar 时,之前的route need to be restored 是在单击bottom bar 中的按钮时。

当点击底部栏的按钮时,其当前路由路径(/a/b/c)被保存,并根据按钮点击恢复之前保存的路由。

从概念上讲,用户会将每个按钮视为一个工作区,并且它的状态永远不会丢失(包括返回堆栈)。用户可以安全地从一个工作区切换到另一个工作区。

当路由为rewinding to root时,如何在Flutter中获取当前路由路径?

【问题讨论】:

  • Navigator 2.0 中添加了许多内容:medium.com/flutter/… 对于新应用,请考虑完全不同的设计。

标签: routing navigation flutter


【解决方案1】:

这应该会给你确切的路线名称

ModalRoute.of(context).settings.name

如果您使用 Navigator.popuntil.. 请查看 Rémi Rousselet https://stackoverflow.com/a/50817399/5921185 的其他答案

【讨论】:

  • 为什么要在您的示例中导入路径包?和解决方案有关系吗?
  • 在导航器上不返回当前路线
  • 这在使用 Navigator.popuntil 后不起作用....
【解决方案2】:

NavigatorState 不公开获取当前路由路径的 API,Route 也不公开确定路由路径的 API。路由可以(并且通常是)匿名的。您现在可以使用 isCurrent 方法确定给定的 Route 是否位于导航器堆栈的顶部,但这对于您的用例来说不是很方便。

我建议您对这个问题采取不同的方法,并且根本不要倒退到根目录。相反,为BottomNavigationBar 的每个窗格使用不同的Navigator 小部件。这样,您就不必在窗格之间切换时倒回堆栈。您可以将 Navigator 小部件包装在 OpacityIgnorePointer 小部件中,以便在它们不应该可见时隐藏它们,而不会破坏它们的堆栈。

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'),
          ),
        ],
      ),
    );
  }
}

【讨论】:

  • 哇!美化。此解决方案还解决了我遇到的其他状态问题。
  • 事实上,我一直在修补StackOpacity,但无法让它工作。我不知道Navigator 可以本地化。 IgnorePointer 是我无法弄清楚的另一个技巧。将两者结合起来,一个内置的Hide-Show Widget 会很好,让它们被发现。
  • 这个奇妙的解决方案有other issue
  • @CollinJackson 如果不包含IgnorePointer 会怎样?我阅读了文档,但仍然不确定它与导航堆栈的关系
【解决方案3】:

发布此答案主要用于存档目的,但正如@ikben 所提到的,获取当前路线及其所有属性的一种方法是ModalRoute.of(context)。这会返回一个ModalRoute,尽管它的名字,它适用于大多数Navigator.push 调用,而不仅仅是showDialog。有用的属性包括Route.settingsRoute.navigatorRoute.isFirst

【讨论】:

    【解决方案4】:

    如果你想通过导航键获取当前路线,可以使用 popUntil 方法:

    String? currentPath;
    navigatorKey.currentState?.popUntil((route) {
      currentPath = route.settings.name;
      return true;
    }); 
    

    【讨论】:

    • 使用嵌套导航键时的完美答案,很好玩!!!
    【解决方案5】:

    我找到了一个更简单的解决方案。我喜欢 StatelessWidget,所以我用的是静态的,但你可以用 StatefulWidget 来做。如果您有分层导航,则需要 StatefulWidget。这是我的 NavDrawer 中的一个图块。 (静态数据不好说,但在 UI 中也不错,只有一个进程在运行一个线程。)

    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);
          },
        );
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-06-04
      • 2021-06-21
      • 1970-01-01
      • 2020-11-21
      • 2016-07-08
      • 2021-05-21
      • 2020-11-16
      • 1970-01-01
      相关资源
      最近更新 更多