作者:韩茹
公司:程序咖(北京)科技有限公司
鸿蒙巴士专栏作家
当年的 Android 中,有的 sp、dp。还有 dpi 等概念。
- dpi,dots per inch,代表屏幕像素密度。
- dp,device independent pixels(设施独立像素,等同于 dip),不依赖于像素
- sp,scale-independent pixels(缩放独立像素,等同于 sip),和 dp 相似,容许由用户自定义文字尺寸大小(如小、失常、大、超大等)
所以在 Android 应用程序的 mipmap 或 drawable 目录下,依据 dpi 的不同分为 ldpi、mdpi、hdpi、xhdpi、xxhdpi、xxxhdpi 等。
HarmonyOS 在借鉴 Android 教训的同时,也提出了翻新。
对于很大一部分程序员用户来说,会比拟纠结这些问题:图片的大小尺寸定义为多大尺寸比拟正当?应该放在什么规范的 dpi 中能力失去更好的适配成果?在 HarmonyOS 中,程序员可不必将工夫和精力过多破费在此。在搁置图片的 media 目录下也没有依照 dpi 来进行辨别。
为了解决因为屏幕规格不同而引起的页面适配问题,HarmonyOS 提供了针对不同屏幕尺寸进行界面自适应适配的 7 种原子布局能力,使设计师能够应用原子布局能力来定义元素在不同尺寸的界面上的自适应规定。详见官网文档:https://developer.harmonyos.c…
HarmonyOS 从新定义了界面换算单位,应用虚构像素作为一台设施针对利用而言所具备的虚构尺寸,是定义利用内参数尺寸的度量单位。虚构像素也是一种可灵便应用和缩放的单位,它与屏幕像素的关系是 1vp 约等于 160dpi 屏幕密度设施上的 1px。在不同密度的设施之间,HarmonyOS 会针对性的转换设施间对应的理论像素值。
一、px
px:像素的单位,1px 代表手机屏幕上的一个像素点。比方常见的手机分辨率有 320×480,480×800,1080×1920 等,这些数值的单位都是 px;因为 px 在不同手机上的大小不同,差异较大,适配性太差,不倡议应用。
因为手机分辨率不同,利用中用到的图片某个固定尺寸大小的图片,或某个固定字号的文本就会因手机分辨力不同而呈现失真或变形的状况,为了更好的适配不同的手机,故而就有了不依赖与像素的单位 sp 与 dp。
二、vp
vp:虚构像素 (virtual pixel) 是一台设施针对利用而言所具备的虚构尺寸(区别于屏幕硬件自身的像素单位)。它提供了一种灵便的形式来适应不同屏幕密度的显示成果。
应用虚构像素 vp,使元素在不同密度的设施上具备统一的视觉体量。
三、fp
fp,font-size pixels,字体像素单位,其大小标准默认状况下与 vp 雷同,但如果开发者在设置中批改了字体显示大小,就会在 vp 的根底上乘以 scale 系数。即默认状况下 1 fp = 1vp,如果设置了字体显示大小,则会依据理论状况主动设置 1fp = 1vp * scale。
四、AttrHelper 工具类
为了不便开发者对尺寸长度的治理,官网提供了 AttrHelper 工具类,可实现 fp、vp、px 之间的互相转换,几乎不要太不便。以下是局部办法:
Modifier and Type | Method | Description |
---|---|---|
static int | fp2px(float value, float density) | Converts a font-size pixel (fp) to a pixel value based on the screen density. |
static int | fp2px(float value, float density, float fontRatio) | Converts a font-size pixel (fp) value to a pixel value based on the screen density and font ratio. |
static int | fp2px(float value, Context context) | Converts a font-size pixel (fp) to a pixel value based on the screen context. |
static float | getDensity(Context context) | Obtains the display density. |
static int | vp2px(float value, float density) | Converts a virtual pixel (vp) to a pixel value based on the screen density. |
static int | vp2px(float value, Context context) | Converts a virtual pixel (vp) to a pixel value based on the screen context. |
另外,除 fp、vp、px 的互相转换 API 以外,该工具类还提供了对于 density、字体名称与其值等的转换方法,十分十分的贴心。详见官网文档:https://developer.harmonyos.c…
在 HarmonyOS 中,咱们想布局一个页面,能够应用 xml 文件,也能够通过代码的模式。这里咱们应用之前讲 PositionLayout 布局的一个例子。
从新创立一个布局文件:position_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<PositionLayout
xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:height="match_parent"
ohos:width="match_parent"
ohos:background_element="#99FDF5E6"
>
<Text
ohos:id="$+id:text1"
ohos:height="50vp"
ohos:width="200vp"
ohos:background_element="#99FFE4B5"
ohos:layout_alignment="horizontal_center"
ohos:text="Title"
ohos:text_size="20fp"
ohos:text_alignment="center"
/>
<Text
ohos:id="$+id:text2"
ohos:height="200vp"
ohos:width="200vp"
ohos:background_element="#99FFE4B5"
ohos:text="Content"
ohos:text_alignment="center"
ohos:text_size="20fp"/>
<Text
ohos:id="$+id:text3"
ohos:height="200vp"
ohos:width="200vp"
ohos:background_element="#99FFE4B5"
ohos:text="Content"
ohos:text_alignment="center"
ohos:text_size="20fp"/>
</PositionLayout>
而后关上 slice 下的 MainAbilitySlice 文件,首先批改一下要加载的布局文件:
super.setUIContent(ResourceTable.Layout_position_layout);
而后获取 Text 组件,并设置 positon,其实就是通过 id 获取 Text 组件,想要设置 X 轴和 Y 轴的偏移量,调用 setPosition()办法,来进行设置即可。
public void setPosition(int coordX, int coordY);//Sets the position of the upper-left corner of a component, relative to the parent layout.
然而该办法的参数为 int 类型,单位为 px。如果想应用 vp 或者 fp 等单位。须要借助于一个类 AttrHelper。
其实在代码中,很多办法的参数设置都是以 px 为单位。
Java 示例代码如下:
package com.example.positionlayout.slice;
import com.example.positionlayout.ResourceTable;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.agp.components.AttrHelper;
import ohos.agp.components.Text;
public class MainAbilitySlice extends AbilitySlice {
@Override
public void onStart(Intent intent) {super.onStart(intent);
super.setUIContent(ResourceTable.Layout_position_layout);
// 获取 Text 组件
Text title = (Text)findComponentById(ResourceTable.Id_text1);
Text content1 = (Text)findComponentById(ResourceTable.Id_text2);
Text content2 = (Text)findComponentById(ResourceTable.Id_text3);
// ohos:position_x="200"
// ohos:position_y="60"
// 这里的参数 200,60,单位都是像素 px。title.setPosition(200, 60);
/*
因为在 xml 布局文件中,咱们应用的是 vp,不是 px,然而 setPosition()办法的单位是 px,所以这里咱们转换一下。须要应用 AttrHelper 类。ohos.agp.components.AttrHelper 类:提供了 vp,fp 到 px 的转换
vp2px(float value, float density)-->static int 基于屏幕密度将虚构像素(vp)转换为像素值。*/
//AttrHelper.vp2px(20, AttrHelper.getDensity(this));// 将 20vp 转为 px
// ohos:position_x="20vp"
// ohos:position_y="100vp"
content1.
(AttrHelper.vp2px(20, AttrHelper.getDensity(this)), AttrHelper.vp2px(100, AttrHelper.getDensity(this)));
// ohos:position_x="150vp"
// ohos:position_y="250vp"
content2.setPosition(AttrHelper.vp2px(150, AttrHelper.getDensity(this)), AttrHelper.vp2px(250, AttrHelper.getDensity(this)));
}
}
而后启动模拟器运行:
<img src=”https://img.chengxuka.com/WX20210607-113258@2x.png/mark” alt=”WX20210607-113258@2x” style=”zoom:50%;” />
这里须要分外强调一下,在设置控件的宽度和高度上,咱们习惯了在 xml 布局中应用 vp 而不应用 px(像素)。在设置字体大小的时候,咱们应用 fp 也不应用 px。
特地鸣谢:
https://www.harmonybus.net/ar…
更多内容:
1、社区:鸿蒙巴士 https://www.harmonybus.net/
2、公众号:HarmonyBus
3、技术交换 QQ 群:714518656
4、视频课:https://www.chengxuka.com