【问题标题】:Can't capture values return from Navigator.of(context).pop("value")无法捕获从 Navigator.of(context).pop("value") 返回的值
【发布时间】:2021-04-10 13:48:34
【问题描述】:

我通过以下方式导航到新屏幕

final result = await Navigator.of(context, rootNavigator: true).push(
      MaterialPageRoute(
        builder: (BuildContext context) => PreLog(             
        ),
      ),
    );

    if (result != null) {
      print("Back");
    }

在 PreLog 里面按照以下方式进入了其他几个屏幕;

 Navigator.of(context, rootNavigator: true).pushReplacement(
        MaterialPageRoute(
          builder: (BuildContext context) => MyMap(
          ),
        ),
      );

在最后一屏我按照以下方式返回;

Navigator.of(context).pop("value");

我希望该值返回到第一个屏幕。但它没有。 如何从最后一个屏幕返回值?


我已根据以下回复修改了我的问题。

在主屏幕中,我正在推送 PopTest 小部件

final result = await Navigator.of(context).push(
      MaterialPageRoute(
        builder: (BuildContext context) => PopTest(),
      ),
    );

    print(result);

我正在从 PopTest 加载另一个替换小部件“PopTest2”

class PopTest extends StatefulWidget {
  @override
  _PopTestState createState() => _PopTestState();
}

class _PopTestState extends State<PopTest> {
  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.start,
      crossAxisAlignment: CrossAxisAlignment.stretch,
      children: [
        RaisedButton(
          child: Text("Exit"),
          onPressed: () {
            Navigator.of(context).pop("value from 1");
          },
        ),
        RaisedButton(
          child: Text("Load Next"),
          onPressed: () async {
            final result2 = await Navigator.of(context).pushReplacement(
              MaterialPageRoute(
                builder: (BuildContext context) => PopTest2(),
              ),
            );
          },
        ),
      ],
    );
  }
}

class PopTest2 extends StatefulWidget {
  @override
  _PopTestState2 createState() => _PopTestState2();
}

class _PopTestState2 extends State<PopTest2> {
  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.start,
      crossAxisAlignment: CrossAxisAlignment.stretch,
      children: [
        RaisedButton(
          child: Text("Exit"),
          onPressed: () {
            Navigator.of(context).pop("value from 2");
          },
        ),
      ],
    );
  }
}

如果我从 PopTest 退出,我会得到一个返回值。

但如果我从 PopTest2 退出,我不会得到返回值。

谁能提供一些帮助?

【问题讨论】:

  • 大家好,谁能提供一些帮助?
  • 我认为问题可能是我将替换推送到推送的小部件。但我不明白为什么我不能返回值......
  • 撞……..

标签: flutter navigation return


【解决方案1】:

您将 rootNavigator 设置为 true,这会将您推送的小部件/屏幕放置到您的应用的根目录中,该应用的后面没有小部件/屏幕。

在代码中省略 rootNavigator:true(默认为 false)

final result = await Navigator.of(context).push(
      MaterialPageRoute(
        builder: (BuildContext context) => PreLog(             
        ),
      ),
    );

Prelog 页面(下)

// result2 is a variable with scope accessible to Navigator.pop()

result2 = await Navigator.of(context).pushReplacement(
        MaterialPageRoute(
          builder: (BuildContext context) => MyMap(
          ),
        ),
      );

//when you are returning back 
Navigator.of(context).pop(result2);


EDITED ANSWER:: (在编辑问题之后)

之前,我错过了您正在推动页面替换。

查看这些图片以获得更好的理解:: Main Screen of App,Screen One,Screen Two

在导航堆栈中,我们有主屏幕(等待 PopTest1 屏幕的结果)和 PopTest1 屏幕。

当您推送 PopTest2 小部件作为替换屏幕时,您的导航堆栈现在具有主屏幕(从 PopTest1 屏幕获取结果)和 PopTest2 屏幕。阅读pushRelpacement api docs

PopTest1 现在被堆栈中的 PopTest2 替换。另外,PopTest1 的“OnPressed 函数”正在等待结果。

这就是您无法为主屏幕带来价值的原因。

你可以解决这个问题

  1. 在 PopTest1 Widget 的 pushReplacement 调用中传递 value 可选参数。查看flutter docs
  2. 使用命名路由。查看Reso Coder's blog

【讨论】:

  • 感谢您的回答。但我需要全屏显示推送的小部件。我该怎么做?
  • 要全屏显示推送的小部件,您需要向底部条码添加一些逻辑,使其以零高度呈现(或根本不呈现),或者使用任何状态管理解决方案(参考flutter.dev/docs/development/data-and-backend/state-mgmt)。我曾经使用 bloc 库 (bloclibrary.dev/#) 来做同样的事情,尽管任何状态管理选项都会做你想做的事。
  • 我已根据您提供的帮助修改了我的问题。在多次推送替换后,我仍然面临如何返回值的问题
  • @Janaka 我已经编辑了答案。希望对你有帮助
猜你喜欢
  • 1970-01-01
  • 2019-08-28
  • 1970-01-01
  • 1970-01-01
  • 2021-03-14
  • 1970-01-01
  • 1970-01-01
  • 2021-07-31
  • 1970-01-01
相关资源
最近更新 更多