| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 移动开发 -> Flutter UI适配详解 —— Flutter开发必看! -> 正文阅读 |
|
[移动开发]Flutter UI适配详解 —— Flutter开发必看! |
Flutter中的宽高单位不同于Android中的dp和IOS中的pt,Flutter奉行另外一种单位,即逻辑像素。
devicePixelRatio表示1逻辑像素在设备上对应的物理像素数(px),不同设备的devicePixelRatio不尽相同,比如我手上的小米8 SE,其devicePixelRatio值为2.75,即在小米8 SE上,1逻辑像素等于2.75物理像素,而在我手中的另一部华为 Mate9上,其devicePixelRatio值为3,即在华为 Mate9上,1逻辑像素等于3物理像素。 (注:devicePixelRatio值可以通过Flutter中的MediaQuery类查看) 这就有点奇怪了,明明小米8 SE比华为 Mate9的分辨率更高,可是小米8 SE的devicePixelRatio值竟然比华为 Mate9的devicePixelRatio值还低,我们以Android中的dp为例,计算这两款手机dp与px的关系。首先,我们需要先计算这两款手机的DPI,根据DPI的计算公式得:
再根据公式得
可以看出,同样是1dp,在小米8 SE上对应的像素数是大于华为 Mate9的。 那么,为什么分辨率高的小米8 SE的devicePixelRatio值要比分辨率低的华为Mate 9还小呢?我们来看看devicePixelRatio是如何计算出来的。 通过源码可以发现 在Android中源码位置>shell/platform/android/io/flutter/view/FlutterView.java
可以看到,devicePixelRatio在Android平台就是DisplayMetrics类中的density,拿density是啥,density是密度的意思,其实就是1dp对应的px数,这就怪了,这怎么跟我们自己算出来的值不一样呢,干脆把DisplayMetrics打印出来看看。
我tm…这dpi的值系统是咋算的,和标准计算公式算出来的不能说一模一样,可以说是毫不沾边啊。 佛了,彻底整蒙圈了,看来这devicePixelRatio是不能直接用了。 在IOS中源码位置>engine/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm
关于这个scale,苹果的官方文档这么介绍
简单讲就是
这个跟IOS中pt的计算方式也不一样吧(我百度的,看到这的IOS的小伙伴,评论里吱一声)。 得,费尽周折,最后发现devicePixelRatio不靠谱,导致Flutter中使用其作为转换的逻辑像素也不靠谱,适配还得另想办法。 flutter_screenUtil这是我在pub.dev上发现的一个Flutter开源工具,与我设想的适配方案一致,秉着不重复造轮子的原则,就直接用它了,它可以解决Flutter在不同端上的适配问题,保持Flutter在不同设备上的UI一致。 flutter_screenUtil的使用简单讲一下flutter_scrrenUtil的使用,官方的介绍点这里 只需在main或跟路由(第一个flutter页面)中调用一次
其中Size中的宽高尺寸可以使用任何单位,dp、pt、px都可以,只要和后面设置使用的单位保持一致就可以。 例如,我这设计图尺寸如下 代码则为
初始化完成后怎么使用呢? 代码如下
注意,因为我们在 width对应的值后面要加上.w,height对应的值后面要加上.h。 ok,宽高除了.w和.h,其实flutter_screenUtil还提供了另外一种设置方式,有时候,我不关心宽高的具体值,我只需要设置某个控件的宽高为手机屏幕宽高的一半,那么这个时候就可以用.sw和.sh这两个属性。
到这里,宽高就适配完成了,那么字体呢? 字体也简单,在字体大小值的后面加.sp就可。
处了上面这些,flutter_screenUtil还有一个.r属性。 这个属性干啥用呢,radius?角度? 不是的,它其实也是宽高的单位,只不过在特殊的情况下才会使用,比如我们要一个宽高都为100dp的按钮,这时候我们再设置width、height为100.w和100.h时,运行起来后会得到一个长方形,惊不惊喜意不意外,这种情况,设置width、height为100.r和100.r即可解决。 flutter_screenUtil的原理flutter_screenUtil的适配方案非常简单粗暴,那就是 — ’比例‘ 拿宽度为例,假如我设计图的宽高尺寸为100dp*200dp,其中有一个10dp宽度的按钮,那么它对应在设备中的宽度就是 > 设备宽度 * 10(控件宽度) / 100(设计图宽度),这个很容易理解吧。 原理理解后,我们去看看.w的代码实现
可以看出.w是通过给num增加扩展方法实现的,其调用了
scaleWidth即为屏幕宽度与设计图宽度的比例。 所以最后 w = _screenWidth * width / uiSize.width; 其他属性,也是如此计算的。 flutter_screenUtil中的问题当你的App在不考虑横屏切换时,以上方式的UI适配基本不会有问题,但是,一旦有横屏的状态,.sp和.r就萎了。 竖屏 横屏 大家一起来找茬。。 这是红色块儿中文字的代码,字体大小用了.sp做适配。
这是绿色块儿的代码,宽高用了.r做适配
直接看.sp和.r的代码,发现这两个方法都使用了
看到这,你明白了吗?为什么横屏比竖屏,发生了文字和宽高的缩小。 因为scaleWidth和scaleHeight是屏幕宽高度和设计图宽高度的比值,横屏状态下手机屏幕的宽高值发生变化,而设计图的宽高值却是写死的,就导致了横屏与竖屏下计算出来的的scaleWidth和scaleHeight值不一样。而scaleWidth和scaleHeight的不一样,又导致了scaleText的不一样,而scaleText的不一样又导致了.sp和.r的不一样,最后,这不一样就体现在了横竖屏下的UI上。 最后如果你的App不考虑横屏,那么flutter_screenUtil中的属性放心用。 如果你的App要考虑横屏的情况,那么.sp和.r属性慎用,字体大小推荐就按flutter中的逻辑像素来,控件长宽相同的情况下推荐都使用.w或.h。 当然,你也可以对.sp和.r的源码进行修改,换成你想要的算法。 参考文章[1] Flutter大小单位详解 |
|
移动开发 最新文章 |
Vue3装载axios和element-ui |
android adb cmd |
【xcode】Xcode常用快捷键与技巧 |
Android开发中的线程池使用 |
Java 和 Android 的 Base64 |
Android 测试文字编码格式 |
微信小程序支付 |
安卓权限记录 |
知乎之自动养号 |
【Android Jetpack】DataStore |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年1日历 | -2025/1/31 10:10:16- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |