HarmonyOS与Android中字号大小与长度单位(sp、dp、vp、fp)比较 原创
一直以来,总有不少人问鸿蒙系统中的字体大小单位fp和尺寸长度单位vp与Android系统中的字体大小单位sp、尺寸长度单位dp有什么区别。在此,就我的理解发表一下愚见。
1. 先来说说Android中的sp、dp吧。其实在Android中除了sp、dp以外,还有另一个不容被忽略的单位px。
(1)px:像素的单位,1px代表手机屏幕上的一个像素点。比如常见的手机分辨率有320×480,480×800,1080×1920等,这些数值的单位都是px;由于px在不同手机上的大小不同,差别较大,适配性太差,不建议使用。
由于手机分辨率不同,应用中用到的图片某个固定尺寸大小的图片,或某个固定字号的文本就会因手机分辨力不同而出现失真或变形的情况,为了更好的适配不同的手机,故而就有了不依赖与像素的单位sp与dp。
(2)为了说明sp与dp,先来了解下dpi。dpi:dots per inch,代表屏幕像素密度。其计算公式为:
::: hljs-center
:::
其中,w表示宽度像素值,h表示高度像素值,size表示屏幕尺寸(英尺)。如某手机屏幕分辩率为1080×1920,屏幕尺寸为5inch,则dpi=√(1080^2 +1920^2 )/5=440。在Android应用程序的mipmap或drawable目录下,根据dpi的不同分为ldpi、mdpi、hdpi、xhdpi、xxhdpi、xxxhdpi等。
(3)dp:device independent pixels(设备独立像素,等同于dip),不依赖于像素,在不同分辨率的手机上可自动缩放。一般定义1dp为160dpi时的一个像素大小,那么,如果手机分辨率是320dpi,则1dp相当于2px。所以dp在不同分辨率的手机上可以自动伸缩,适配性较好,建议项目中的尺寸等长度单位使用dp。
(4)sp:scale-independent pixels(缩放独立像素,等同于sip),和dp类似,允许由用户自定义文字尺寸大小(如小、正常、大、超大等),当文字尺寸是“正常”时,1sp=1dp=0.00625inch(英寸),当文字尺寸是“大”或“超大”时,1sp>1dp=0.00625inch。因此,sp亦可缩放,以适配不同分辨率的手机。建议项目中的文字大小的单位使用sp。
(5)px&dp
在每英寸160点(即160dpi)的显示器上,1dp=1px。
在320480分辨率,像素密度为160时,1dp=1px。
在480800分辨率,像素密度为240时,1dp=1.5px。
计算公式:px=dp x(dpi/160)
(6)各种dpi比较(密度density指屏幕上每平方英寸(2.542 平方厘米)中含有的像素点数量,不同于分辨率):
ldpi(low):适用于低密度(ldpi)屏幕(0-120dpi)的资源,1dp=3/4px。
mdpi(medium):适用于中密度(mdpi)屏幕(120-160dpi)的资源,1dp=1px。
hdpi(high):适用于高密度(hdpi)屏幕(160-240dpi)的资源,1dp=1.5px。
xhdpi(extra-high):适用于超高密度(xhdpi)屏幕(240-320dpi)的资源,1dp=2px。
xxhdpi(extra-extra-high):适用于超超高密度(xxhdpi)屏幕(320-480dpi)的资源,1dp=3px。
xxxhdpi(extra-extra-extra-high):适用于超超超高密度(xxxhdpi)屏幕(480-640dpi)的资源,1dp=4px。
(7)drawable/mipmap各种文件夹对应图片大小
drawable-ldpi:36×36
drawable-mdpi:48×48
drawable-hdpi:72×72
drawable-xhdpi:96×96
drawable-xxhdpi:144×144
drawable-xxxhdpi:192×192
(8)dp,sp,px相互转化代码
/**
* dp转换为px
*
* @param context
* @param value 单位dp
* @return
*/
public static int dp2px(Context context, int value) {
float v = context.getResources().getDisplayMetrics().density;
return (int) (v * value + 0.5f);
}
/**
* sp转换为px
*
* @param context
* @param value 单位sp
* @return
*/
public static int sp2px(Context context, int value) {
float v = context.getResources().getDisplayMetrics().scaledDensity;
return (int) (v * value + 0.5f);
}
/**
* px转换为dp
*
* @param context
* @param value
* @return
*/
public static int px2dp(Context context, int value) {
float v = context.getResources().getDisplayMetrics().density;
return (int) (value / v + 0.5f);
}
/**
* px转换为sp
*
* @param context
* @param value
* @return
*/
public static int px2sp(Context context, int value) {
float v = context.getResources().getDisplayMetrics().scaledDensity;
return (int) (value / v + 0.5f);
}
了解了Android中的sp、dp是否有种头大的感觉呢,不要紧,接下来看看鸿蒙就轻松了。
2. HarmonyOS在借鉴Android经验的同时,也提出了创新。
对于很大一部分程序员用户来说,会比较纠结这些问题:图片的大小尺寸定义为多大尺寸比较合理?应该放在什么标准的dpi中才能得到更好的适配效果?在HarmonyOS中,程序员可不必将时间和精力过多花费在此。在放置图片的media目录下也没有按照dpi来进行区分。
为了解决由于屏幕规格不同而引起的页面适配问题,HarmonyOS 提供了针对不同屏幕尺寸进行界面自适应适配的7种原子布局能力,使设计师可以使用原子布局能力来定义元素在不同尺寸的界面上的自适应规则。详情请移步(特别神奇,强烈建议去看看,附加的视频很生动、很形象):https://developer.harmonyos.com/cn/docs/design/des-guides/atomic_layout_ability-0000001053683035
原子布局能力分为:“自适应变化能力”和“自适应布局能力”两类。其中自适应变化能力有2种:“拉伸能力”和“缩放能力”。缩放能力的实现需要强大的自主定位能力做辅助。HarmonyOS提供的栅格系统作为一种辅助布局的定位工具,对于移动设备的意义主要有:
优势1:给布局提供一种可循的规律,解决多尺寸多设备的动态布局问题。
优势2:给系统提供一种统一的定位标注,保证各模块各设备的布局一致性。
优势3:给应用提供一种灵活的间距调整方法,满足特殊场景布局调整的可能性。
栅格系统通过操作Margin、Column、Gutter3个属性来实现其强大的自主缩放功能。详情请移步(莫要被惊到哦)https://developer.harmonyos.com/cn/docs/design/des-guides/grid_system-0000001053923059。
HarmonyOS 重新定义了界面换算单位,使用虚拟像素作为一台设备针对应用而言所具有的虚拟尺寸,是定义应用内参数尺寸的度量单位。虚拟像素也是一种可灵活使用和缩放的单位,它与屏幕像素的关系是 1vp 约等于 160dpi 屏幕密度设备上的 1px。在不同密度的设备之间,HarmonyOS 会针对性的转换设备间对应的实际像素值。HarmonyOS中除vp外,还有fp、px,其中px和Android的含义一样,下面说明一下vp和fp。
(1)vp:virtual pixels,指一台设备针对应用而言所具有的虚拟尺寸。目前官方文档中给出来穿戴设备(手表)和智慧屏中的建议间隔尺寸标准。
(2)fp:font-size pixels,字体像素单位,其大小规范默认情况下与vp相同,但如果开发者在设置中修改了字体显示大小,就会在vp的基础上乘以scale系数。即默认情况下 1 fp = 1vp,如果设置了字体显示大小,则会根据实际情况自动设置 1fp = 1vp * scale。官方建议的常见的字体标准可参考https://harmonyos.51cto.com/posts/4382。
(3)为了方便开发者对尺寸长度的管理,官方提供了AttrHelper工具类,可实现fp、vp、px之间的相互转换,简直不要太方便。
PS:偷懒一下,没有翻译,不过大家应该都认识的,O(∩_∩)O哈哈~。
另外,除fp、vp、px的相互转换API以外,该工具类还提供了关于density、字体名称与其值等的转换方法,非常非常的贴心。详见https://developer.harmonyos.com/cn/docs/documentation/doc-references/attrhelper-0000001054518726#ZH-CN_TOPIC_0000001054518726__convertValueToInt-java_lang_String-int-。
总之,个人感觉相比Android来说,鸿蒙在字体大小与长度设置长做了很多创新工作,大大方便了开发人员,你觉得呢?
特别鸣谢:
https://www.jianshu.com/p/8c078b988ceb
https://www.jianshu.com/p/a895dbed1c3b
👍👍👍