自定义可复用Modal Bottom Sheet报错:缺少State build方法
解决“缺少State build方法”报错并实现可复用Modal Bottom Sheet
报错原因
你最初的代码把ModalBottomSheet定义为StatefulWidget,但对应的_ModalBottomSheetState类是抽象类State的子类,必须强制重写build方法——这就是报错的根本原因。但实际上,你不需要把弹窗封装成StatefulWidget,因为它本质是一个触发弹窗的工具逻辑,做成普通工具类的静态方法更简洁。
正确实现代码
可复用弹窗工具类
class ModalBottomSheet { // 静态方法,直接通过类名调用 static void show(BuildContext context, {required Function(int) onPressed}) { showModalBottomSheet( context: context, isScrollControlled: true, backgroundColor: Colors.transparent, builder: (BuildContext context) { return Container( height: 200, decoration: const BoxDecoration( color: Colors.white, borderRadius: BorderRadius.only( topLeft: Radius.circular(20), topRight: Radius.circular(20), ), ), child: Padding( padding: const EdgeInsets.all(10), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ TextButton( onPressed: () { Navigator.pop(context); // 先关闭弹窗 onPressed(1); // 触发回调并传参1(相机) }, child: const Text('CAMERA'), ), TextButton( onPressed: () { Navigator.pop(context); // 先关闭弹窗 onPressed(2); // 触发回调并传参2(相册) }, child: const Text('GALLERY'), ), ], ), ), ); }, ); } }
主页面调用代码
// 触发弹窗的地方调用 ModalBottomSheet.show(context, onPressed: (index) { if (index == 1) { pickImage(ImageSource.camera); } else { pickImage(ImageSource.gallery); } }, );
关键修正点
- 把弹窗逻辑改成静态方法,无需实例化类,直接通过
ModalBottomSheet.show()调用 - 将
onPressed作为方法参数传入,解决原代码中局部变量无法接收外部参数的问题 - 修正
TextButton的onPressed写法:原代码的onPressed: (1)是语法错误,改为无参回调() { ... },内部调用传入索引的回调 - 添加
Navigator.pop(context):点击按钮后先关闭弹窗,再执行后续逻辑,符合用户操作习惯 - 补全所有未闭合的Widget(比如
Column、Container),修复语法错误
内容的提问来源于stack exchange,提问作者Giovanni
相关产品推荐
相关产品推荐

