Flutter中WillPopScope在AppBar返回按钮不生效的解决方法
解决方案
问题出在AppBar的自定义返回按钮直接调用Navigator.pop(context),跳过了WillPopScope的onWillPop逻辑拦截。要让它和物理返回键行为一致,只需复用同一套返回判断逻辑即可,步骤如下:
1. 提取返回判断逻辑为独立方法
把onWillPop中的逻辑抽成一个异步方法,方便两处调用:
Future<bool> _handleBackPressed() async { if (selectedIndex == 3 && stockListData.length != 0) { final value = await showDialog<bool>( context: context, builder: (context) { Widget continueButton = FlatButton( color: Colors.black, child: Text( "OK", style: TextStyle(color: Colors.white), ), onPressed: () { Navigator.of(context).pop(true); }); return AlertDialog( titlePadding: EdgeInsets.only(top: 13), title: Container( height: 40, child: Center( child: Text( "Alert", style: TextStyle(color: blackColor), ), ), ), content: Text( "If you leave this page then your added stock will be deleted.", textAlign: TextAlign.center, style: TextStyle(fontSize: 12), ), actions: [ continueButton, ], actionsAlignment: MainAxisAlignment.center, ); }); return value == true; } else { Navigator.of(context).pop(); return false; } }
2. 修改WillPopScope的onWillPop
让它直接调用这个提取后的方法:
WillPopScope( onWillPop: _handleBackPressed, child: Scaffold( // ... 其他原有代码 ), )
3. 修改AppBar返回按钮的点击事件
将原来直接Navigator.pop的逻辑替换为调用上述方法:
leading: Builder( builder: (BuildContext context) { return IconButton( icon: Icon(Icons.arrow_back_ios_rounded), onPressed: () async { await _handleBackPressed(); }, tooltip: '', ); }, ),
完整修改后的代码示例
return WillPopScope( onWillPop: _handleBackPressed, child: Scaffold( backgroundColor: Colors.white, appBar: AppBar( title: Text( "Portfolio Review", style: TextStyle(fontSize: tSize16), ), leading: Builder( builder: (BuildContext context) { return IconButton( icon: Icon(Icons.arrow_back_ios_rounded), onPressed: () async { await _handleBackPressed(); }, tooltip: '', ); }, ), elevation: 0, backgroundColor: skyBlue, ), body: SingleChildScrollView(), ), ); // 提取的返回判断方法 Future<bool> _handleBackPressed() async { if (selectedIndex == 3 && stockListData.length != 0) { final value = await showDialog<bool>( context: context, builder: (context) { Widget continueButton = FlatButton( color: Colors.black, child: Text( "OK", style: TextStyle(color: Colors.white), ), onPressed: () { Navigator.of(context).pop(true); }); return AlertDialog( titlePadding: EdgeInsets.only(top: 13), title: Container( height: 40, child: Center( child: Text( "Alert", style: TextStyle(color: blackColor), ), ), ), content: Text( "If you leave this page then your added stock will be deleted.", textAlign: TextAlign.center, style: TextStyle(fontSize: 12), ), actions: [ continueButton, ], actionsAlignment: MainAxisAlignment.center, ); }); return value == true; } else { Navigator.of(context).pop(); return false; } }
这样修改后,无论是物理返回键还是AppBar的自定义返回按钮,都会触发相同的确认对话框逻辑,保证行为一致。
内容的提问来源于stack exchange,提问作者Deepak
相关产品推荐
相关产品推荐

