【问题标题】:flutter - android back button does not call onWillPop of WillPopScopeflutter - android后退按钮不调用WillPopScope的onWillPop
【发布时间】:2020-06-02 19:48:07
【问题描述】:

我想退出我的申请。我已经实现了一个 WillPopScope,但看起来 onWillPop 函数根本没有被调用。我尝试了很多方法,例如将 WillPopScope 与 Scaffold 交换,更改函数的返回值,但它看起来不像预期的那样工作。

我的代码:

Future<bool> _willPopCallback() async {
  exit(0);
  // await showDialog or Show add banners or whatever
  // then
  return true; // return true if the route to be popped
}


return Scaffold(
    appBar: MyAppBar(
      leading: DrawerAction(),
      title: Text(AppLocalizations.of(context).textCapitalized('home_page')),
      onSearch: (searchTerms) => this.search(searchTerms, context),
    ),
    body: new WillPopScope(
      onWillPop: _willPopCallback, // Empty Function.
      child: //my screen widgets

我不确定这是我应该向 Flutter 报告的错误还是我做错了什么。很高兴根据要求提供更多代码。

我试过了:

exit(0);
Navigator.of(context).pop();
SystemChannels.platform.invokeMethod('SystemNavigator.pop');

提前致谢!

【问题讨论】:

    标签: flutter dart


    【解决方案1】:

    我设法解决了我的问题,我认为这是一个非常特殊的案例,但它仍然可能对某人有所帮助。

    TL;DR:确保您的小部件中没有多个脚手架

    我在菜单导航器中使用IndexedStack,显然是用脚手架包裹的。堆栈的页面也有 Scaffold,使用这种组合 WillPopScope 既不能在导航器页面中工作,也不能在其堆栈页面中工作。我通过删除堆栈页面中的所有脚手架并在控制器中只有一个来解决。这样我就成功地正确使用了WillPopScope

    【讨论】:

    • 是否有任何选项可以在小部件结束之前获取回调,我们也使用多个Scaffolds
    • 如果嵌套多个Scaffolds,则需要删除它们,然后您的 willPopCallback 已经在小部件结束之前,您是决定是否通过返回布尔值来结束它的人跨度>
    • 我有多个脚手架,因为我需要在某些子部分中设置不同的应用栏和导航......必须有另一种方法来解决这个问题。
    • 我很高兴你找到了solution,我仍然不能 100% 确定哪些小部件可以嵌套和不能嵌套使用 WillPopScope 的基本逻辑是什么。有趣的事实是,由于使用了IndexedStack,我们都采用了类似的解决方案。
    【解决方案2】:

    首先不要使用exit(0)。在 Android 环境下可能没问题,但如果应用程序以编程方式自行关闭,Apple 将不允许该应用程序出现在应用商店中。

    onWillPopdocs 中,它清楚地提到函数应该解析为布尔值。

    Future<bool> _willPopCallback() async {
       // await showDialog or Show add banners or whatever
       // then
       return Future.value(true);
    }
    

    仅当您的当前页面是导航堆栈的根时才有效。

    【讨论】:

    • 我已经更新了我的答案,exit(0) 是我最后一次绝望地尝试看到它的工作,但我已经尝试了我能在网上找到的一切。现在我将尝试使用 Future.value(false); 更改 false,但是当我按下返回时,看起来函数 根本没有被调用
    • @Gicminos 你试过用WillPopScope 小部件包裹你的脚手架
    • 是的,我做到了!将再次尝试Future.value(false);
    • 我几乎可以肯定,为了让您的页面“弹出”,您需要返回 Future.value(true),而不是 false。
    • 我会再试一次 Future.value(true) 但我再说一遍,函数 _willPopCallback() 不会被 WillPopScope 调用!
    【解决方案3】:

    修改代码以返回 WillPopScope,并将 Scaffold 作为子级。

    return new WillPopScope(
        onWillPop: _willPopCallback,
        child: new Scaffold(
         //then the rest of your code...
    

    【讨论】:

      【解决方案4】:

      我知道我来晚了,但问题仍然存在。 也许我找到了正确的解决方案。 确保您将 MaterialApp 传递给 runApp 方法,如下所示:

      runApp(MaterialApp(home: MyFirstPage()));
      

      这适用于我所有应用程序的小部件。如果您不想使用它,只需将您的小部件包装在 MaterialApp 中,但不要忘记在每个 MaterialApp 实例中创建一个新的 Navigator,所以对我来说,我只是像上面那样创建了一个,在我的所有页面中我只使用了脚手架,一切都是好的。

      【讨论】:

        【解决方案5】:

        我一直在与此作斗争,最初认为它与嵌套的 Scaffold 小部件有关,正如 OP 在上面的回答中提到的那样。我对此进行了测试,但仍然遇到同样的问题。我的答案是我的根ScaffoldNavigator 的孩子。一旦我将Scaffold 作为Navigator 的子项删除,它就起作用了。值得庆幸的是,我不需要在根级别使用Navigator,因为我使用的是IndexedStack,其中包含多个Navigator 小部件。

        【讨论】:

          【解决方案6】:

          我也遇到了同样的问题,但经过大量搜索,我发现这个错误与我的父容器有关。

          return WillPopScope(
                onWillPop: () => _onWillPop(),
                child: Scaffold(
                  appBar: AppBar(
                    backgroundColor: Colors.transparent,
                    ...
                    ],
                  ),
          

          【讨论】:

            【解决方案7】:

            另一个可能的原因:我的 _onWillPop() 实现引发了异常,而 _onWillPop() 中的代码被忽略了。日志中没有出现异常。

            我通过在 _onWillPop() 中使用 TRY/CATCH 并处理所有代码路径来解决它。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2021-03-22
              • 2021-11-25
              • 2021-01-19
              • 2020-12-04
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多