flutter - android返回按钮未调用WillPopScope的onWillPop

fafcakar  于 2023-01-06  发布在  Flutter
关注(0)|答案(8)|浏览(455)

我想退出我的应用程序。我已经实现了一个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');

先谢了!

piok6c0g

piok6c0g1#

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

TL;DR:确保小部件中没有多个支架

我在我的菜单导航器中使用IndexedStack,显然是用一个支架 Package 的。堆栈的页面也有支架,使用这个组合WillPopScope在导航器页面和堆栈页面中都不工作。我通过删除堆栈页面中的所有支架并在控制器中只保留一个来解决这个问题。这样我就成功地正确使用了WillPopScope

sqserrrh

sqserrrh2#

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

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

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

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

px9o7tmv

px9o7tmv3#

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

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

qxsslcnc4#

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

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

这对我所有的应用程序的小部件都有效。如果你不想使用它,只需将小部件 Package 在MaterialApp中,但不要忘记,在每个MaterialApp示例中都会创建一个新的导航器,所以对我来说,我只是如上所述创建了一个导航器,在我所有的页面中,我只是使用了scaffold,一切都很好。

vs91vp4v

vs91vp4v5#

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

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

7eumitmz6#

另一个可能的原因:我的_onWillPop()实现抛出了一个异常,_onWillPop()中的代码被忽略。2该异常没有出现在日志中。
我通过使用TRY/CATCH inside _onWillPop()并处理所有代码路径解决了这个问题。

pqwbnv8z

pqwbnv8z7#

我一直在与这个问题作斗争,最初认为它与嵌套的Scaffold小部件有关,就像OP在上面的回答中提到的那样。尽管我测试了这个问题,但仍然有同样的问题。对我来说,答案是我的根ScaffoldNavigator的孩子。当我删除作为Navigator孩子的Scaffold时,它就工作了。谢天谢地,我在根级别不需要Navigator,因为我使用的是IndexedStack,其中有多个Navigator小部件。

c0vxltue

c0vxltue8#

这是一个迟来的答案,但我希望能帮助别人。
@Gicminos的回答是正确的。如果你有嵌套的scaffold,那么PopScope将无法工作。我想补充一些信息,以防你需要。
我有一个包含bottomNavBar的支架,bottomNav中的每个Item都是一个Navigator,其子节点是支架(您注意到,此时有嵌套的支架)。
这是我的MainScaffold,包含底部的栏:

...

_navigatorKeys = {
      TabItem.tabOne: tabOneKey,
      TabItem.tabTwo: GlobalKey<NavigatorState>(),
    };
...
@override
  Widget build(BuildContext context) {
    return WillPopScope(
      onWillPop: () async {
        //check if there are pages in stack so it can pop;
        var navigatorState =(_navigatorKeys.values.toList([_selectedIndex]as GlobalKey<NavigatorState>).currentState;
        if ( navigatorState !=null) {
          if (!await navigatorState
              .maybePop()) return true;
        }
        return false;
      },
      child: Scaffold(
        body: SafeArea(
          child: IndexedStack(
            index: _selectedIndex,
            children: _pages,
          ),
        ),
        resizeToAvoidBottomInset: true,
        bottomNavigationBar: Container(...)
        ...
}

如果你 Package 了一个WillPopScope小部件,你的孩子也喜欢下面的代码:

@override
  Widget build(BuildContext context) {
    var t = AppLocalizations.of(context)!;

    return WillPopScope(
      onWillPop: () async {
        debugPrint("test");
        return true;
      },
      child: Scaffold(...)
}

onWillPop都将被调用(在主框架和子框架中)。在示例中,第一个将仅在可以时弹出(导航器堆栈中有页面),第二个将在第一个之后立即调用,并且在返回之前调用debugPrint函数

相关问题