Flutter中如何关闭showModalBottomSheet?(附权限请求代码场景)
解决方案:Flutter中关闭showModalBottomSheet的两种方法
结合你的代码场景,当位置权限获取成功后需要关闭之前弹出的底部弹窗,这里有两种实用的实现方式:
方法一:利用Navigator直接关闭(简单快捷)
showModalBottomSheet本质是通过Flutter的Navigator栈来管理的,所以直接调用Navigator.of(context).pop()就能关闭当前显示的弹窗。这种方式适合弹窗是在当前页面上下文弹出的场景:
修改你的requestPermission方法即可:
Future<void> requestPermission(Permission permission) async { final status = await permission.request(); if(status != PermissionStatus.granted){ _showModalBottomSheet(context); }else{ // 关闭modal bottom sheet Navigator.of(context).pop(); Position position = await Geolocator().getCurrentPosition(desiredAccuracy: LocationAccuracy.high); print(position.latitude); print(position.longitude); bloc.coordinate(position.latitude.toString() + position.longitude.toString()); } }
方法二:持有弹窗控制器(更精准可控)
如果需要更精确的控制(比如存在多个弹窗、需要在其他逻辑中关闭),可以保存showModalBottomSheet返回的控制器,通过控制器主动关闭:
步骤1:定义控制器变量
把原有的PersistentBottomSheetController替换为ModalBottomSheetController:
ModalBottomSheetController? _modalBottomSheetController;
步骤2:弹出弹窗时保存控制器
修改你的_showModalBottomSheet方法,保存返回的控制器:
void _showModalBottomSheet(BuildContext context) { // 先关闭已存在的弹窗,避免重复弹出 _modalBottomSheetController?.close(); _modalBottomSheetController = showModalBottomSheet( context: context, builder: (context) { return Container( padding: EdgeInsets.all(16), child: Text('请前往系统设置开启位置权限'), ); }, ); }
步骤3:权限成功后关闭弹窗
在权限获取成功的分支里调用控制器的close()方法:
Future<void> requestPermission(Permission permission) async { final status = await permission.request(); if(status != PermissionStatus.granted){ _showModalBottomSheet(context); }else{ // 关闭弹窗并清空控制器 _modalBottomSheetController?.close(); _modalBottomSheetController = null; Position position = await Geolocator().getCurrentPosition(desiredAccuracy: LocationAccuracy.high); print(position.latitude); print(position.longitude); bloc.coordinate(position.latitude.toString() + position.longitude.toString()); } }
额外场景处理:用户前往设置开启权限后返回
考虑到用户可能会在弹窗提示后,离开应用去系统设置开启权限再返回,你可以利用已经混入的WidgetsBindingObserver监听应用生命周期,自动关闭弹窗并获取位置:
@override void didChangeAppLifecycleState(AppLifecycleState state) { super.didChangeAppLifecycleState(state); // 当应用从后台回到前台时检查权限 if (state == AppLifecycleState.resumed) { Permission.location.status.then((status) { if (status == PermissionStatus.granted) { _modalBottomSheetController?.close(); _modalBottomSheetController = null; // 重新获取位置信息 Geolocator().getCurrentPosition(desiredAccuracy: LocationAccuracy.high).then((position) { print(position.latitude); print(position.longitude); bloc.coordinate(position.latitude.toString() + position.longitude.toString()); }); } }); } }
最后记得在页面销毁时清理资源:
@override void dispose() { WidgetsBinding.instance.removeObserver(this); // 关闭可能残留的弹窗 _modalBottomSheetController?.close(); super.dispose(); }
内容的提问来源于stack exchange,提问作者Jsoon
相关产品推荐
相关产品推荐

