在日常应用页面布局设计时,开发者需要知道每个组件的样式及位置,这时就需要了解像素单位及相互转换方法,ArkUI 开发框架提供了4种像素单位供开发者使用,分别是: px 、 vp 、 fp 和 lpx ,框架采用 vp 为基准数据单位,本篇就简单为大家介绍下像素单位的基本知识与像素单位转换API的使用。通过像素转换案例,向开发者讲解了如何使用像素单位设置组件的尺寸、字体的大小以及不同像素单位之间的转换方法。
效果呈现
本例最终效果如下:
运行环境
本例基于以下环境开发,开发者也可以基于其他适配的版本进行开发:
- IDE: DevEco Studio 3.1 Release
- SDK: Ohos_sdk_public 3.2.12.5(APIVersion 9 Release)
实现思路
本篇案例主要功能包括:①像素单位基本知识介绍;②像素单位转换相关API的使用。
- 构建入口页面:该页面包含两个button组件,通过点击按钮事件,实现到详细页面的跳转
- 像素单位介绍页面:
- 构建IntroducitonViewModel.ets
创建自定义接口IntroductionItem,根据IntroductionItem接口参数,创建对象数组INTRODUCE_LIST,向对象数组INTRODUCE_LIST中填充像素单位介绍页面所需参数内容。
- 构建IntroducitonPage.ets
通过ForEach循环渲染上一步骤中对象数组中的每个Item;通过if判断组件的显隐,同时添加样式,完成像素介绍页面。
- 像素转换页面:
- 构建ConvertionViewModel.ets
创建自定义接口ConversionItem,根据ConversionItem接口参数,创建对象数组ConversionViewModel,向对象数组ConversionViewModel中填充像素转换页面所需参数内容。
- 构建ConvertionPage.ets
通过ForEach循环渲染上一步构建的ConversionViewModel的每个子菜单Item,同时添加样式,构建像素介绍页面。
开发步骤
1.构建入口页面:该页面包含两个button按钮,通过点击按钮事件,实现到详细页的跳转。 具体代码如下:
// entry/src/main/ets/pages/IndexPage.ets
import router from '@ohos.router';
@Entry
@Component
struct IndexPage {
// 定义jumpPage方法,实现路由跳转
jumpPage(url: string) {
router.pushUrl({
url })
}
build() {
Column({
space: 24 }) {
Button('像素介绍')
.height('40vp')
.width('100%')
.backgroundColor($r('app.color.blue_background'))
// 点击时回调jumpPage方法,跳转到pages/IntroductionPage页面
.onClick(() => this.jumpPage('pages/IntroductionPage'))
Button('像素转换')
.height('40vp')
.width('100%')
.backgroundColor($r('app.color.blue_background'))
// 点击时回调jumpPage方法,跳转到pages/ConversionPage页面
.onClick(() => this.jumpPage('pages/ConversionPage'))
}
.backgroundColor($r('app.color.page_background'))
.justifyContent(FlexAlign.Center)
.padding(24)
.width('100%')
.height('100%')
}
}
2.像素单位介绍页面创建。 此页面主要系统介绍像素单位的概念,包含px、vp、lpx以及fp,并在页面中 为Text组件的宽度属性设置不同的像素单位(如px、vp、lpx),fp像素单位则设置为Text组件的字体大小。
- 从效果图看,此页面由4个功能相同的菜单组成,我们先构建功能菜单。创建IntroducitonViewModel.ets定义每个子功能菜单Item。 具体代码如下:
// entry/src/main/ets/viewmodel/IntroducitonViewModel.ets
// 创建自定义接口,定义每个Item中的内容
interface IntroductionItem {
name: string;
title: string;
subTitle: string;
value: string;
smallFontSize: number;
largeFontSize: number;
}
// 根据自定义接口IntroductionItem,填充内容
const INTRODUCE_LIST: IntroductionItem[] = [
{
name: 'px',
title: '屏幕物理像素单位。',
subTitle: null,
value: '200px',
smallFontSize: 0,
largeFontSize: 0
},
{
name: 'vp',
title:'屏幕密度相关像素,根据屏幕像素密度转换为屏幕物理像素。',
value:'200vp',
subTitle:'像素密度为160dpi的设备上1vp=1px,1vp对应的物理屏幕像素=(屏幕像素密度/160)px',
smallFontSize: 0,
largeFontSize: 0
},
{
name: 'lpx',
title:'视窗逻辑像素单位,lpx单位为实际屏幕宽度与逻辑宽度(通过designWidth配置)的比值。',
subTitle: null,
value: '200lpx',
smallFontSize: 0,
largeFontSize: 0
},
{
name: 'fp',
title:'字体像素,与vp类似,随系统字体大小设置变化。',
subTitle:'默认情况下与vp相同,即1vp=1fp,如果用户手动调整了系统字体,scale为缩放比例,设置后的字体大小(单位fp) = 设置前的字体大小 * scale',
value: '',
smallFontSize: 14,
largeFontSize: 24
}
];
// 定义类IntroductionViewModel,获取像素介绍页面的数据
class IntroductionViewModel {
getIntroductionList() {
let introductionItems = INTRODUCE_LIST;
return introductionItems;
}
}
let introductionViewModel = new IntroductionViewModel();
export default introductionViewModel as IntroductionViewModel;
渲染像素单位介绍页面,通过ForEach循环渲染上一步构建的IntroductionViewModel的每个子菜单Item;通过if判断组件的显隐,为显示的组件,添加样式,构建像素介绍页面。 具体代码如下:
// entry/src/main/ets/pages/IntroducitonPages.ets
import IntroductionViewModel from '../viewmodel/IntroductionViewModel';
interface IntroductionItem {
name: string;
title: Resource;
subTitle: Resource;
value: string;
smallFontSize: number;
largeFontSize: number;
}
@Extend(Text) function titleTextStyle() {
.fontColor($r('app.color.title_font'))
.fontFamily('HarmonyHeiTi_Medium')
.fontWeight(500)
}
@Entry
@Component
struct IntroductionPage {
build() {
Column() {
Navigation() {
List({
space: 12 }) {
//通过ForEach循环渲染Item,构建像素介绍页面
ForEach(IntroductionViewModel.getIntroductionList(), (item: IntroductionItem) => {
//渲染每个Item
ListItem() {
Column() {
Text(item.name)
.titleTextStyle()
.fontSize('16fp')
Text(item.title)
.titleTextStyle()
.fontSize('14fp')
.fontFamily('HarmonyHeiTi')
.lineHeight('20fp')
.margin({
top: '8vp'})
.fontWeight(400)
// subTitle非空,添加Text组件,显示subTitle内容,同时添加样式;不存在则不显示
if (item.subTitle) {
Text(item.subTitle)
.titleTextStyle()
.opacity(0.6)
.lineHeight('16fp')
.fontSize('12fp')
.fontFamily($r('app.string.HarmonyHeiTi'))
.margin({
top: '20vp' })
.fontWeight(400)
}
// value非空,添加Text组件且通过宽度属性设置不同的像素单位
if (item.value.length > 0) {
Text(item.value)
.titleTextStyle