目前移动端的设备已经很是多,而且不一样的设备手机屏幕也不相同。前端
目前作移动端开发都要针对不一样的设备进行必定的适配,不管是移动原生开发、小程序、H5页面。vue
Flutter中如何针对不一样的手机屏幕来进行适配呢?咱们一块儿来聊聊这个话题。web
在进行Flutter开发时,咱们一般不须要传入尺寸的单位,那么Flutter使用的是什么单位呢?算法
在Flutter开发中,咱们使用的是对应的逻辑分辨率小程序
获取屏幕上的一些信息,能够经过MediaQuery:api
// 1.媒体查询信息
final mediaQueryData = MediaQuery.of(context); // 2.获取宽度和高度 final screenWidth = mediaQueryData.size.width; final screenHeight = mediaQueryData.size.height; final physicalWidth = window.physicalSize.width; final physicalHeight = window.physicalSize.height; final dpr = window.devicePixelRatio; print("屏幕width:$screenWidth height:$screenHeight"); print("分辨率: $physicalWidth - $physicalHeight"); print("dpr: $dpr"); // 3.状态栏的高度 // 有刘海的屏幕:44 没有刘海的屏幕为20 final statusBarHeight = mediaQueryData.padding.top; // 有刘海的屏幕:34 没有刘海的屏幕0 final bottomHeight = mediaQueryData.padding.bottom; print("状态栏height: $statusBarHeight 底部高度:$bottomHeight"); 复制代码
获取一些设备相关的信息,可使用官方提供的一个库:数据结构
dependencies:
device_info: ^0.4.2+1 复制代码
假如咱们有下面这样一段代码:app
class HYHomePage extends StatelessWidget {
@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("首页"), ), body: Center( child: Container( width: 200, height: 200, color: Colors.red, alignment: Alignment.center, child: Text("Hello World", style: TextStyle(fontSize: 30, color: Colors.white),), ), ), ); } } 复制代码
上面的代码在不一样屏幕上会有不一样的表现:less
很明显,若是按照上面的规则,在iPhone5上面,尺寸过大,在iPhone6plus上面尺寸太小编辑器
在开发中,咱们应该能够根据不一样的屏幕来完成尺寸的缩放
在前端开发中,针对不一样的屏幕常见的适配方案有下面几种:
这里我采用小程序的rpx来完成Flutter的适配
小程序中rpx的原理是什么呢?
那么咱们就能够经过上面的计算方式,算出一个rpx,再将本身的size和rpx单位相乘便可:
咱们本身来封装一个工具类:
class HYSizeFit {
static MediaQueryData _mediaQueryData; static double screenWidth; static double screenHeight; static double rpx; static double px; static void initialize(BuildContext context, {double standardWidth = 750}) { _mediaQueryData = MediaQuery.of(context); screenWidth = _mediaQueryData.size.width; screenHeight = _mediaQueryData.size.height; rpx = screenWidth / standardWidth; px = screenWidth / standardWidth * 2; } // 按照像素来设置 static double setPx(double size) { return HYSizeFit.rpx * size * 2; } // 按照rxp来设置 static double setRpx(double size) { return HYSizeFit.rpx * size; } } 复制代码
初始化HYSizeFit类的属性:
class HYHomePage extends StatelessWidget {
@override Widget build(BuildContext context) { // 初始化HYSizeFit HYSizeFit.initialize(context); return null; } } 复制代码
使用rpx来完成屏幕适配:
class HYHomePage extends StatelessWidget {
@override Widget build(BuildContext context) { HYSizeFit.initialize(context); return Scaffold( appBar: AppBar( title: Text("首页"), ), body: Center( child: Container( width: HYSizeFit.setPx(200), height: HYSizeFit.setRpx(400), color: Colors.red, alignment: Alignment.center, child: Text("Hello World", style: TextStyle(fontSize: HYSizeFit.setPx(30), color: Colors.white),), ), ), ); } } 复制代码
咱们来看一下实现效果:
若是每次咱们须要将如今的宽度或者高度,去使用HYSizeFit.setPx(200)或者HYSizeFit.setRpx(400)相似的方式去适配,显然看起来很是麻烦。
有没有更好的方案能够实现了?好比 200.px或者400.rpx,很是的清晰简洁
固然能够,咱们须要依赖Dart语言的一个特性:extension
好比咱们如今对String类型扩展:
// 步骤一:扩展代码
extension NumberParsing on String { int parseInt() { return int.parse(this); } // ··· } // 步骤二:调用代码 // 导入扩展类对应的模块 import 'string_apis.dart'; // 使用里面的方法 print('42'.padLeft(5)); // 使用String原有的方法 print('42'.parseInt()); // 使用String扩展的方法 复制代码
显然,数字(好比200、200.0)有对应的包装类int、double,咱们能够对其进行扩展:
1.对int类型扩展
import '../shared/size_fit.dart';
extension IntFit on int { double get px { return HYSizeFit.setPx(this.toDouble()); } double get rpx { return HYSizeFit.setRpx(this.toDouble()); } } 复制代码
2.对double类型扩展
import '../shared/size_fit.dart';
extension DoubleFit on double { double get px { return HYSizeFit.setPx(this); } double get rpx { return HYSizeFit.setRpx(this); } } 复制代码
如何使用了?
import './extension/double_extension.dart';
import './extension/int_extension.dart'; print(200.px); // 在不一样屏幕下200px是不一样的值 print(400.rpx); // 在不一样屏幕下400rpx是不一样的值 复制代码
备注:全部内容首发于公众号,以后除了Flutter也会更新其余技术文章,TypeScript、React、Node、uniapp、mpvue、数据结构与算法等等,也会更新一些本身的学习心得等,欢迎你们关注