Flutter Navigation 弹出到索引 1

Posted

技术标签:

【中文标题】Flutter Navigation 弹出到索引 1【英文标题】:Flutter Navigation pop to index 1 【发布时间】:2018-09-15 07:06:48 【问题描述】:

我正在递归地将路线添加到导航器。可能有 20 个或更多视图。 Pop 像宣传的那样工作,但我想弹出到索引 1 并删除所有推送历史记录。有没有办法用类似... returntoIndex0 ...

      new ListTile(
        title: new RaisedButton(
          child: new Text("POP"),
          onPressed: () 
            var route = new MaterialPageRoute(
              builder: (BuildContext context) =>
                  new NextPage3(value:"hi there from 3"),
            );
            Navigator.pop(context);
          ,
        ),
      ),

【问题讨论】:

【参考方案1】:

如果不使用命名路由,可以使用

Navigator.of(context).popUntil((route) => route.isFirst);

【讨论】:

Navigator.popUntil(context, (Route route) => route.isFirst);这对我来说也很好用。 由于某种原因,当我使用.push.then()时,当我使用.popUntil((route) => route.isFirst;)时它不会解析.then 谢谢伙计。没有名称路由就找不到如何 popUntil 这就是我一直在寻找的答案!谢谢! 能否请人解释一下popUntil((route) => route.isFirst) 会做什么?正如我用来将所有 backstack 弹出到 home 小部件一样,但它也会从 backstack 中弹出 home 小部件。【参考方案2】:

如果您确切知道应该执行多少次弹出:

例如 2 次弹出:

count = 0;
Navigator.popUntil(context, (route) 
    return count++ == 2;
);

【讨论】:

太棒了,这是我一直在为我的应用寻找的解决方案。 在我的情况下完美运行,我没有使用命名路由! 略有变化,因为至少在我们的应用程序中很难跟踪弹出次数。我用过:Navigator.popUntil(context, (route) => route.isFirst); 效果很好。 pop 获得更好的用户体验,它比 push 快得多。 我知道这一点,但 UI 受到干扰,因为我们同时弹出到两个屏幕。我认为必须有几秒钟的延迟。你说什么??????【参考方案3】:

如果你使用MaterialPageRoute创建路由,你可以使用这个命令:

Navigator.popUntil(context, ModalRoute.withName(Navigator.defaultRouteName))

Navigator.defaultRouteName 反映了启动应用程序的路由。这是更详细地说明它的一段代码:

child: InkWell(
          child: Row(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            children: <Widget>[
              Image(
                image: AssetImage('assets/img/ic_reset.png'),),
              Text('Change my surgery details',
                style: TextStyle(color: Colors.blue, decoration: TextDecoration.underline),),
            ],
          ),
          onTap: () =>
              Navigator.popUntil(context, ModalRoute.withName(Navigator.defaultRouteName))
        ),

希望这会有所帮助。

【讨论】:

【参考方案4】:

对我来说,我在推送新页面时使用了这个:

widget = MyWidget();
Route route = CupertinoPageRoute(builder: (context) => widget, settings:RouteSettings(name: widget.toStringShort()));
Navigator.push(context, route);

然后返回特定页面:

Navigator.of(context).popUntil((route) => route.settings.name == "MyWidget");

【讨论】:

太棒了!工作得很好!【参考方案5】:

使用文档中提到的popUntil 方法

典型用法如下:

Navigator.popUntil(context, ModalRoute.withName('/login'));

【讨论】:

我会进行更多实验,但我的问题是我正在动态构建。我会即时添加 NextPage .... 如果数据库需要它。我一直在寻找一种可以破坏导航历史并为 / 休息的方法。我阅读了文档并看到了 PopUntil。只是想要一些想法。 我有一个情况。我有 Screen1 和 Screen2。我从 Screen1 导航到 Screen2。现在我想要的是当我从 Screen2 后按时。该应用程序应该完成。 @AnkitShukla Navigator.of(context) .pushNamedAndRemoveUntil('/2ndScreen', (Route r) =&gt; r == null); 请看***.com/questions/60985638/flutter-navigation【参考方案6】:

这里 Dashboard() 是屏幕名称。所以这将弹出所有屏幕并转到 Dashboard() 屏幕。

Navigator.of(context).pushAndRemoveUntil(
                  MaterialPageRoute(builder: (c) => Dashboard()),
                  (route) => false)

【讨论】:

它会弹出所有屏幕,直到到达“仪表板屏幕”,但它也会忘记“仪表板屏幕”之前所有以前访问过的屏幕,这是其中非常奇怪的一部分。任何建议记住“仪表板屏幕”的前几页。例如。如果用户从主屏幕进入仪表板,则在仪表板的下一个屏幕(例如更新配置文件屏幕)上执行某些操作。如果用户从“更新配置文件屏幕”重定向到“仪表板”,则“仪表板屏幕”应该忘记“更新配置文件屏幕”但记住“主屏幕”。后退按钮应始终显示在“仪表板屏幕”上。我们该怎么办? 在弹出屏幕的过程中没有办法保留所有中间屏幕。 屏幕流程如下:1) 主屏幕 -> 2) 仪表板屏幕 -> 3) 更新配置文件屏幕 当用户提交“更新配置文件屏幕”时,它应该被重定向到仪表板屏幕并忘记“更新配置文件屏幕”。仪表板屏幕应始终具有后退按钮,当用户点击仪表板屏幕的后退按钮时,应重定向到主屏幕。现在告诉我将使用哪个“Navigator.of(context).XXXXX”函数。谢谢。 非常简单,只需在提交“更新配置文件屏幕”后调用 Navigator.of(context).pop() 即可。它将转到 2) 仪表板屏幕。仪表板屏幕中的后退按钮会将您重定向到 1) 主屏幕。【参考方案7】:

你也可以这样做

Navigator.of(context)
            .pushNamedAndRemoveUntil('/Destination', ModalRoute.withName('/poptillhere'),arguments: if you have any);

用例是转到所需的屏幕并根据需要在其间弹出屏幕。

更多信息,您可以查看Post Explaining other Solutions

【讨论】:

【参考方案8】:
//========================================================
          new ListTile(
            title: new RaisedButton(
              child: new Text("POP until"),
              onPressed: () 
                var route = new MaterialPageRoute(
                  builder: (BuildContext context) =>
                      new NextPage3(value:"hi there from 3"),
                );
               //Navigator.pop(context, ModalRoute.withName('/'));
                Navigator.popUntil(context,ModalRoute.withName('/'));                
              ,
            ),
          ),
//========================================================

将 .pop 替换为 .popUntil,实际上非常优雅。

【讨论】:

【参考方案9】:

我在这篇文章中尝试了其他答案,但不知何故导致了以下异常。

To safely refer to a widget's ancestor in its dispose() method, save a reference to the ancestor by calling dependOnInheritedWidgetOfExactType() in the widget's didChangeDependencies() method.

The relevant error-causing widget was
    MaterialApp 
lib/main.dart:72
When the exception was thrown, this was the stack
#0      Element._debugCheckStateIsActiveForAncestorLookup.<anonymous closure> 
package:flutter/…/widgets/framework.dart:3781
#1      Element._debugCheckStateIsActiveForAncestorLookup 
package:flutter/…/widgets/framework.dart:3795
#2      Element.dependOnInheritedWidgetOfExactType 
package:flutter/…/widgets/framework.dart:3837
#3      Theme.of 
package:flutter/…/material/theme.dart:128
#4      XXxxXX.build.<anonymous closure> 
package:xxx/widgets/xxx.dart:33
...
════════════════════════════════════════════════════════════════════════════════

以下答案解决了这个问题。 https://***.com/a/52048127/2641128

Navigator.pushNamedAndRemoveUntil(context, '/', (_) => false);

【讨论】:

【参考方案10】:

这总是让我得到预期的结果。 并且会弹出到当前 Navigator 栈的路由

 Navigator.of(context, rootNavigator: true).pop();

【讨论】:

以上是关于Flutter Navigation 弹出到索引 1的主要内容,如果未能解决你的问题,请参考以下文章

如何将 android 导航 backstack 弹出到某个片段?

Swift iOS - 如何使用 NavigationController 弹出到不同的 SegmentControl 索引

如何在弹出到根视图 Swift 后立即更改选项卡?

UINavigationController - 返回按钮弹出到某个 UIViewController

弹出到 ExpoKit 后,Expo 不起作用

不会从子视图控制器弹出到父视图