前言
做移动端开发的小伙伴都知道,针对不同型号和尺寸的手机要进行页面适配,且Android和iOS适配方案各不相同,那flutter端如何进行适配呢?以下为近期flutter开发过程中关于适配的一些学习和记录~~~~
比例适配
说到flutter屏幕适配,就不得不提到插件flutter_screenutil,提到flutter_screenutil就不得不说以下几点
1.初始化
- 1.2版本之前这么玩
默认宽1080px
默认高1920px
allowFontScaling为false,即不跟随系统字体大小设置变化
初始化单位为px
ScreenUtil.init(context);
ScreenUtil.init(context, width: 750, height: 1334);
ScreenUtil.init(context, width: 750, height: 1334, allowFontScaling :true);
需要把context传进去,因为内部是通过MediaQuery
来获取屏幕尺寸等相关信息的
MediaQueryData mediaQuery = MediaQuery.of(context);
- 1.2版本以后这么玩
ScreenUtil.init();
ScreenUtil.init(width: 750, height: 1334);
ScreenUtil.init(width: 750, height: 1334, allowFontScaling: true);
无需再传context,因为内部是通过单例window
来获取屏幕尺寸等相关信息的
- 初始化的位置
重点来了,为保证在使用插件的适配方法前,插件已经初始化完成,初始化方法要放在MaterialApp的home
中,并且只有放在StatefulWidget
的build方法中才会生效~
补充说明:这里不关心是纯flutter项目,还是flutter和原生混合开发栈的项目,初始化的位置保持一致
2.使用方法
- 通用写法
ScreenUtil().setWidth(540)
ScreenUtil().setHeight(200)
ScreenUtil().setSp(24)
ScreenUtil().setSp(24, allowFontScalingSelf: true)
ScreenUtil().setSp(24, allowFontScalingSelf: false)
- dart sdk >= 2.6可使用简化写法
按宽适配: 540.w
按高适配: 200.h
字体适配: 24.sp
- 其他属性和方法
ScreenUtil.pixelRatio
ScreenUtil.screenWidth 物理宽度
ScreenUtil.screenHeight 物理高度
ScreenUtil.bottomBarHeight 底部安全区高度
ScreenUtil.statusBarHeight 状态栏高度(含刘海)px
ScreenUtil.textScaleFactor 系统字体
ScreenUtil().scaleWidth 实际宽度的dp与设计稿px的比例
ScreenUtil().scaleHeight 实际高度的dp与设计稿px的比例
3.实用扩展
作为iOS开发,之前都是以pt为参照进行比例适配的,且架构组已经定义了一套适配相关常量,传px进去不太方便,所以需要对flutter_screenutil进行扩展
公司设计图是以iPhone X的尺寸提供的即物理设备尺寸为375x812,像素比例为750x1624,像素密度比为2
初始化仍用px来初始化
ScreenUtil.init(width: 750, height: 1624);
dart sdk 2.7正式支持extension-method
,即为已有类扩展方法,从 flutter_screenutil 这种540.w
写法点进去,我们可以看到
extension SizeExtension on num {
num get w => ScreenUtil().setWidth(this);
num get h => ScreenUtil().setHeight(this);
num get sp => ScreenUtil().setSp(this);
num get ssp => ScreenUtil().setSp(this, allowFontScalingSelf: true);
num get nsp => ScreenUtil().setSp(this, allowFontScalingSelf: false);
}
flutter_screenutil为num类扩展了一系列简写方法,那我们当然可以按照它这种方式进行扩展
/// 设计图像素密度比px/pt
const pixelRatio = 2;
/// 传pt即可
extension ZRSizeExtension on num {
num get zW => ScreenUtil().setWidth(this * pixelRatio);
num get zH => ScreenUtil().setHeight(this * pixelRatio);
num get zSp => ScreenUtil().setSp(this * pixelRatio);
num get zSsp => ScreenUtil().setSp(this * pixelRatio, allowFontScalingSelf: true);
num get zNsp => ScreenUtil().setSp(this * pixelRatio, allowFontScalingSelf: false);
}
4.遇到问题
- extension-method
使用extension-method
来扩展方法,需要Dart sdk最低版本为2.6,否则会报错:
This requires the 'extension-methods' experiment to be enabled.
网上提供的解决方案:
第一步:修改 pubspec.yaml
environment:
sdk: ">=2.6.0 <3.0.0"
第二步:执行flutter pub get
第三步:重启 AndroidStudio
- 赋值报错
Container(
padding: const EdgeInsets.only(10.zW),
child: Row(),
)
Arguments of a constant creation must be constant expressions.
解决方案:去掉const即可
参考文章
UI设计中px、pt、ppi、dpi、dp、sp之间的关系
Dart/Flutter - 扩展方法(ExtensionMethod)