Flutter中基于Getx的响应式UI无法随屏幕尺寸动态更新
问题解决:Getx实现动态响应式尺寸适配
原问题中,Dimensions类的静态变量仅在初始化时获取一次屏幕尺寸,横竖屏切换或窗口缩放时无法更新,导致UI不能自适应。下面给出两种解决方案,既保留原有的简洁调用方式,又实现尺寸动态更新。
方案一:使用Getx控制器监听屏幕变化
步骤1:创建尺寸管理控制器
import 'package:get/get.dart'; class DimensionsController extends GetxController { RxDouble screenHeight = Get.context!.height.obs; RxDouble screenWidth = Get.context!.width.obs; @override void onInit() { super.onInit(); // 监听屏幕尺寸变化,自动更新响应式变量 ever(Get.mediaQuery, (MediaQueryData mediaQuery) { screenHeight.value = mediaQuery.size.height; screenWidth.value = mediaQuery.size.width; }); } // 所有尺寸改为getter,每次访问都会基于最新屏幕尺寸计算 double get pageView => screenHeight.value / 2.64; double get pageViewContainer => screenHeight.value / 3.84; double get pageTextContainer => screenHeight.value / 7.03; // 高度相关 double get height10 => screenHeight.value / 84.4; double get height15 => screenHeight.value / 56.27; double get height20 => screenHeight.value / 42.2; double get height45 => screenHeight.value / 18.76; double get height30 => screenHeight.value / 28.13; // 宽度相关 double get width10 => screenHeight.value / 84.4; double get width15 => screenHeight.value / 56.27; double get width20 => screenHeight.value / 42.2; double get width30 => screenHeight.value / 28.13; double get width45 => screenHeight.value / 18.76; // 字体大小 double get font20 => screenHeight.value / 42.2; double get font26 => screenHeight.value / 42.2; double get font16 => screenHeight.value / 52.75; // 圆角 double get radius15 => screenHeight.value / 56.27; double get radius20 => screenHeight.value / 42.2; double get radius30 => screenHeight.value / 28.13; // 图标大小 double get iconSize24 => screenHeight.value / 35.17; double get iconSize16 => screenHeight.value / 52.75; // ListView尺寸 double get listViewImageSize => screenWidth.value / 3.25; double get listViewTextSize => screenWidth.value / 3.9; // 美食详情页尺寸 double get foodImageSize => screenHeight.value / 2.41; // 底部导航栏高度 double get bottomHeightBar => screenHeight.value / 6.25; // 启动页图片尺寸 double get splashImg => screenHeight.value / 3.375; }
步骤2:初始化控制器
在App入口处初始化控制器,确保全局可用:
void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { Get.put(DimensionsController()); // 初始化尺寸控制器 return GetMaterialApp( title: 'Flutter Demo', theme: ThemeData(primarySwatch: Colors.blue), home: const HomePage(), ); } }
步骤3:简化调用(可选)
如果想保留原有的Dimensions.xxx调用方式,创建一个封装类:
class Dimensions { static DimensionsController get _controller => Get.find<DimensionsController>(); static double get pageView => _controller.pageView; static double get pageViewContainer => _controller.pageViewContainer; static double get pageTextContainer => _controller.pageTextContainer; static double get height10 => _controller.height10; static double get height15 => _controller.height15; static double get height20 => _controller.height20; static double get height45 => _controller.height45; static double get height30 => _controller.height30; static double get width10 => _controller.width10; static double get width15 => _controller.width15; static double get width20 => _controller.width20; static double get width30 => _controller.width30; static double get width45 => _controller.width45; static double get font20 => _controller.font20; static double get font26 => _controller.font26; static double get font16 => _controller.font16; static double get radius15 => _controller.radius15; static double get radius20 => _controller.radius20; static double get radius30 => _controller.radius30; static double get iconSize24 => _controller.iconSize24; static double get iconSize16 => _controller.iconSize16; static double get listViewImageSize => _controller.listViewImageSize; static double get listViewTextSize => _controller.listViewTextSize; static double get foodImageSize => _controller.foodImageSize; static double get bottomHeightBar => _controller.bottomHeightBar; static double get splashImg => _controller.splashImg; }
使用方式
和原代码完全一致,无需修改现有UI代码:
SizedBox( width: Dimensions.width10, ),
核心原理
- 使用
RxDouble响应式变量存储屏幕尺寸,值变化时自动通知依赖的UI组件重建 - 通过
ever(Get.mediaQuery, ...)监听系统媒体查询的变化,实时更新屏幕尺寸值 - 所有尺寸参数改为getter方法,每次访问都会基于最新的屏幕尺寸计算,保证数值动态性
内容的提问来源于stack exchange,提问作者abdalla mohamed
相关产品推荐
相关产品推荐

