如何在ScreenUtil组件中使用AppSpacing常量类实现屏幕适配?
解决flutter_screenutil与AppSpacing常量类适配问题
你推测的没错,问题出在AppSpacing的静态成员初始化时机早于ScreenUtil的初始化。flutter_screenutil的.h/.w扩展方法依赖ScreenUtil内部的初始化状态(基于ScreenUtilInit的designSize),而你的static final成员在类加载阶段就会被赋值,这时候ScreenUtil还没完成初始化,导致计算出的间距是错误的默认值,自然无法生效。
以下是几种可行的解决方案:
方案1:改用Getter方法(推荐)
把静态成员改为Getter,这样每次访问时才会执行.h/.w的计算,此时ScreenUtil已经完成初始化:
class AppSpacing { static EdgeInsets get top20bottom20Left10 => EdgeInsets.only( top: 20.h, bottom: 20.h, left: 50.w, ); // 其他间距也用同样方式定义 static EdgeInsets get horizontal10 => EdgeInsets.symmetric(horizontal: 10.w); }
使用方式和之前完全一致:
Container( margin: AppSpacing.top20bottom20Left10, // ... )
方案2:延迟初始化静态成员
使用late关键字延迟成员初始化,在ScreenUtilInit完成后手动触发初始化:
class AppSpacing { static late final EdgeInsets top20bottom20Left10; static late final EdgeInsets horizontal10; // 统一初始化方法 static void init() { top20bottom20Left10 = EdgeInsets.only(top:20.h, bottom:20.h, left:50.w); horizontal10 = EdgeInsets.symmetric(horizontal:10.w); } }
然后在ScreenUtilInit的builder中调用初始化:
ScreenUtilInit( designSize: const Size(750, 1622), builder: (context, child){ AppSpacing.init(); // 确保ScreenUtil初始化后再执行 return MaterialApp( title: 'Flutter Demo', debugShowCheckedModeBanner: false, theme: ThemeData(primarySwatch: Colors.blue), home: child, ); }, child: MyHomePage(title: 'Flutter Demo Home Page'), ),
方案3:基于上下文的工具类(可选)
如果需要更灵活的适配,可以把Spacing方法和上下文绑定,通过ScreenUtil.of(context)获取实例:
class AppSpacing { static EdgeInsets top20bottom20Left10(BuildContext context) { final screenUtil = ScreenUtil.of(context); return EdgeInsets.only( top: screenUtil.setHeight(20), bottom: screenUtil.setHeight(20), left: screenUtil.setWidth(50), ); } }
使用时需要传入上下文:
Container( margin: AppSpacing.top20bottom20Left10(context), // ... )
内容的提问来源于stack exchange,提问作者IThank
相关产品推荐
相关产品推荐

