[英]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
小部件有關。 我對此進行了測試,但仍然遇到同樣的問題。 我的答案是我的根Scaffold
是Navigator
的孩子。 當我作為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.