【问题标题】:Flutter: How do I pop dialog as well as current page?Flutter:如何弹出对话框以及当前页面?
【发布时间】:2020-12-08 07:06:54
【问题描述】:

下面是代码。

  1. 从主页导航到登录页面
    ElevatedButton(
              onPressed: () => Navigator.of(context, rootNavigator: true)
                  .push(MaterialPageRoute(
                fullscreenDialog: true,
                builder: (context) => UserLoginPage(),
              )),
              child: Text('Login to continue'),
            ),

登录页面内部:

BlocConsumer<UserAuthCubit, UserAuthState>(
            listener: (context, state) {
              if (state is UserAuthorized) {
                Navigator.of(context, rootNavigator: true).pop();
              }
              if (state is UserAuthWaiting) {
                showModalBottomSheet(
                    useRootNavigator: true,
                    isDismissible: false,
                    context: context,
                    builder: (context) {
                      return WillPopScope(
                        onWillPop: () async => false,
                        child: Center(
                          child: Text(state.msg),
                        ),
                      );
                    });
                dialog = true;
              } else {
                if (dialog) {
                  Navigator.of(context, rootNavigator: true).pop();
                  dialog = false;
                }
              }
            },
            builder: (context, state) { // some widget code... }

当状态为UserAuthorized时,我想弹出对话框和LoginPage,返回到最后一页即首页。但是,使用上面的代码,有时它可以工作,而有时,主页也会弹出。 我尝试了,无论是否将 rootNavigator 设置为 true,但无法实现我的目标。

请帮助我了解我在这里缺少什么。

我已经在How to dismiss flutter dialog? 这里检查了答案。

【问题讨论】:

    标签: flutter flutter-bloc


    【解决方案1】:

    你可以简单地使用

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

    更新:

    如果你不知道应该弹出多少页面,那么你应该使用

    Navigator.push(context, MaterialPageRoute(builder: (context)=>YourMaterialClassName(), settings: RouteSettings(name: "nameOfYourClass")));
    

    当你推送你的材料类时。

    然后在弹出的时候使用

    Navigator.popUntil(context, (route) => route.settings.name == "nameOfYourClass");
    

    【讨论】:

    • 我真的可以利用你的建议。帮助我深入研究了机制。我尝试了第二个代码(我认为它更干净)。但是,我可以在 Navigator.popUntil 之后使用额外的 Navigator.pop(context) 来实现我的目标,因为除了我的登录页面之外,所有路由都会弹出。我认为 Navigator.popUntil 意味着不断弹出路线,并在谓词返回 true 时停止;所以它停在登录页面。让我知道我的想法是否正确。
    【解决方案2】:

    我建议在对话后返回true,而不是使用Navigator.of(context).pop()

    或者你可以尝试使用

    Navigator.of(context).pushReplacement(
      MaterialPageRoute(builder: (context) => HomePage()),
    )
    

    通过这样做,您将 LoginPage 替换为 HomePage。

    【讨论】:

    • pushReplacement 将清除后台堆栈。 例如,用户从屏幕 1 > 屏幕 2 与对话框 -> 屏幕 3 导航。在屏幕 3 中调用 Navigator.pop() 将导致由于从屏幕 1 转到屏幕 2 的历史记录已清除,因此变为空白/黑屏。他无法返回屏幕 2 或 1。
    • 我的意思是,如果你没有退出 IMO,你为什么还要回到 LoginPage,但如果你不会清除屏幕历史记录,那么我不建议这个答案
    • 没错,但如果他想要 Navigator.pop() 怎么办。想要使用 Navigator.pop() 是有原因的。 Tbh,他不应该首先使用 Navigator 离开登录页面。他应该使用流来获取用户的当前登录状态。我也明白你的意思@Aldy Yuan,但我们应该让他选择在他想调用 Navigator.pop() 时调用。
    • 我同意使用流会容易得多并且避免样板,我也同意他想要 Navigator.pop() 而不是 pushReplacements。这是我唯一的建议,无论如何我会尽快删除它,谢谢
    • 您可以在此处保留您的答案。如果他愿意,他可以选择使用你的答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多