Flutter GetX底部弹窗高度调整与Controller释放问题求解
问题根源
Get.bottomSheet唤起的弹窗属于GetX路由栈管控范围,弹窗关闭时GetX会自动回收绑定的Controller实例,符合内存管理预期,但默认配置下弹窗容器会撑满最大可用高度,默认用法无法直接自定义高度。- 原生
showModalBottomSheet唤起的弹窗属于Flutter框架路由管控范围,不在GetX路由监听链路内,GetX无法感知弹窗销毁事件,不会自动回收弹窗内注入的Controller,存在内存泄漏风险。
可行方案
方案1:直接用Get.bottomSheet实现自定义高度(推荐,无额外内存处理成本)
Get.bottomSheet本身就是对showModalBottomSheet的封装,原生弹窗支持的所有配置参数它都支持,之前无法调整高度是默认配置的问题,只要加两个配置就能自由控制高度:
class MainPage extends StatelessWidget { const MainPage({super.key}); @override Widget build(BuildContext context) { return TextButton( onPressed: () { Get.bottomSheet( // 外层套高度容器,自由设置你需要的高度 SizedBox( height: MediaQuery.of(context).size.height * 0.4, // 示例为屏幕高度的40%,也可写固定像素值 child: const HomePage(), ), // 关键配置:把弹窗默认背景设为透明,否则默认容器会撑满可用高度 backgroundColor: Colors.transparent, enableDrag: false, // 需要的禁止拖拽配置可正常生效 isDismissible: true, // 其他样式配置和原生弹窗完全一致,比如圆角、阴影等 shape: const RoundedRectangleBorder( borderRadius: BorderRadius.vertical(top: Radius.circular(16)), ), ); }, child: const Text("唤起底部弹窗"), ); } } class GetC extends GetxController {} class HomePage extends StatelessWidget { const HomePage({super.key}); @override Widget build(BuildContext context) { final GetC controller = Get.put(GetC()); return Container( decoration: const BoxDecoration( color: Colors.white, borderRadius: BorderRadius.vertical(top: Radius.circular(16)), ), child: const Text("自定义高度弹窗,Controller自动回收"), ); } }
这个方案完全走GetX的路由管控逻辑,弹窗关闭时绑定的GetC会被自动回收,不需要写额外的内存处理代码。
方案2:用原生showModalBottomSheet时手动回收Controller
如果有特殊场景必须用原生showModalBottomSheet,只要在弹窗关闭后手动调用GetX的删除方法回收实例即可:
TextButton( onPressed: () async { // 等待弹窗关闭 await showModalBottomSheet( context: context, builder: (context) => const HomePage(), enableDrag: false, ); // 弹窗销毁后手动删除对应Controller实例 Get.delete<GetC>(); }, child: const Text("唤起底部弹窗"), )
注意:如果注入Controller时传了
tag参数,删除时也要传入相同的tag才能正确匹配实例:Get.delete<GetC>(tag: "你设置的tag值")
内容的提问来源于stack exchange,提问作者user19471304
相关产品推荐
相关产品推荐

