Flutter:基于showBottomSheet实现返回Future的异步函数
解决方案
要实现用showBottomSheet替代showModalBottomSheet并保持异步返回值的效果,核心是利用Completer将PersistentBottomSheetController的关闭事件转换为Future。具体实现如下:
Future<YourReturnType?> popup(BuildContext context) async { final completer = Completer<YourReturnType?>(); final controller = Scaffold.of(context).showBottomSheet( (context) => YourBottomSheetWidget( // 在BottomSheet内部触发关闭时调用此回调 onClose: (returnValue) { Navigator.of(context).pop(); completer.complete(returnValue); }, ), ); // 监听BottomSheet被动关闭(比如滑动关闭)的情况,确保Future总能完成 controller.closed.then((_) { if (!completer.isCompleted) { completer.complete(null); } }); return completer.future; }
关键细节说明
- Completer的作用:手动控制
Future的完成状态,不管BottomSheet是主动点击关闭还是被动滑动关闭,都能通过它传递返回值。 - 监听closed事件:
PersistentBottomSheetController的closed属性是一个Future,当BottomSheet被关闭时触发,用来处理用户未主动传递返回值的场景,避免函数一直处于等待状态。 - 内部Widget逻辑:在你的BottomSheet内部,点击确认按钮等需要关闭的时机,调用传入的
onClose回调并传递返回值,同时执行Navigator.pop关闭BottomSheet。
如果习惯在BottomSheet内部直接用Navigator.pop传递值,也可以用这种写法:
Future<YourReturnType?> popup(BuildContext context) async { final completer = Completer<YourReturnType?>(); final controller = Scaffold.of(context).showBottomSheet( (context) => Builder( builder: (innerContext) { return YourBottomSheetWidget( onConfirm: () { final returnValue = YourReturnType(); // 构造你的返回值 Navigator.of(innerContext).pop(returnValue); }, ); }, ), ); // 直接通过closed事件获取Navigator.pop传递的值 controller.closed.then((result) { completer.complete(result as YourReturnType?); }); return completer.future; }
这种方式下,Navigator.pop传递的值会被controller.closed的Future接收,直接同步给completer即可完成异步返回。
内容的提问来源于stack exchange,提问作者stackunderflow
相关产品推荐
相关产品推荐

