簡體   English   中英

flutter - android 后退按鈕不調用 WillPopScope 的 onWillPop

[英]flutter - android back button does not call onWillPop of WillPopScope

我想退出我的應用程序。 我已經實現了 WillPopScope,但看起來根本沒有調用 onWillPop function。 我嘗試了很多事情,比如用 Scaffold 交換 WillPopScope,更改 function 的返回值,但看起來它沒有按預期工作。

我的代碼:

 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');

提前致謝!

首先,永遠不要使用exit(0) 在Android環境下可能沒問題,但如果應用程序以編程方式自行關閉,Apple將不允許該應用程序出現在應用程序商店中。

onWillPop文檔中,它清楚地提到函數應該解析為布爾值。

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

這僅在您當前頁面是導航堆棧的根時才有效。

我設法解決了我的問題,我認為這是一個非常特殊的案例,但它仍然可能對某人有所幫助。

TL;DR:確保您的小部件中沒有多個 Scaffolds

我在我的菜單導航器中使用IndexedStack ,顯然用 Scaffold 包裹。 堆棧的頁面也有 Scaffold,通過這種組合, WillPopScope在導航器頁面和堆棧頁面中都不起作用。 我通過刪除堆棧頁面中的所有 Scaffolds 並在控制器中只有一個來解決。 通過這種方式,我設法正確地使用了WillPopScope

修改代碼返回WillPopScope,將Scaffold作為子項。

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

我知道我來晚了,但問題仍然存在。 也許我找到了正確的解決方案。 確保將 MaterialApp 傳遞給 runApp 方法,如下所示:

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

這適用於我所有應用程序的小部件。 如果您不想使用它,只需將您的小部件包裝在 MaterialApp 中,但不要忘記在每個 MaterialApp 實例中都會創建一個新的導航器,所以對我來說,我剛剛創建了一個如上所述的導航器,在我的所有頁面中,我只使用了腳手架,一切都是好的。

我也遇到了同樣的問題,但經過大量搜索,我發現此錯誤與我的父容器有關。

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

另一個可能的原因:我對 _onWillPop() 的實現拋出了一個異常,並且 _onWillPop() 中的代碼被忽略了。 異常沒有出現在日志中。

我通過在 _onWillPop() 中使用 TRY/CATCH 並處理所有代碼路徑來解決它。

我一直在與這個問題作斗爭,最初認為它與 OP 在上面的回答中提到的嵌套Scaffold小部件有關。 我對此進行了測試,但仍然遇到同樣的問題。 我的答案是我的根ScaffoldNavigator的孩子。 當我作為Navigator的孩子移除Scaffold ,它就起作用了。 幸運的是,我在根級別不需要Navigator ,因為我使用的是一個IndexedStack ,其中包含多個Navigator小部件。

這是一個遲到的答案,但我希望可以幫助某人。

@Gicminos 的回答是正確的。 如果你有嵌套的腳手架 willPopScope 不工作。 我想添加一些信息以備不時之需。

我有一個包含 bottomNavBar 的腳手架。 bottomNav 中的每個 Item 都是一個 Navigator,其子項是 Scaffold(您注意到此時內嵌有腳手架)。

這是我的包含底欄的 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(...)
        ...
}

如果你用 WillPopScope 小部件包裝,你的孩子也喜歡下面的代碼:

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

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

onWillPop 都將被調用(在主腳手架和子腳手架中)。 在這個例子中,第一個只有在可以的情況下才會彈出(導航器堆棧中有頁面),第二個將在第一個之后立即調用,它會在返回之前調用 debugPrint function

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM