资源管理
本节笔者向读者介绍一下 OpenHarmony 应用的资源分类和资源的访问以及应用开发使用的像素单位以及各单位之间相互转换的方法。
资源分类
移动端应用开发常用到的资源比如图片,音视频,字符串等都有固定的存放目录,OpenHarmony 把这些应用的资源文件统一放在 resources 目录下的各子目录中便于开发者使用和维护, resoures 目录包括两大类,一类为 base 目录与限定词目录,另一类为 rawfile 目录。新建 OpenHarmony 应用,默认生成的资源目录如下所示:

base 目录与限定词目录下面可以创建资源组目录(包括 element 、 media 、animation 、 layout 、 graphic 、 profile ),用于存放特定类型的资源文件,各资源目录说明如下图所示:

资源访问
OpenHarmony 应用资源分为两类,一类是应用资源,另一类是系统资源,它们的资源访问方式如下:
访问应用资源
base 目录下的资源文件会被编译成二进制文件并且给这些资源赋予唯一的 ID ,使用相应资源的时候通过资源访问符 $r('app.type.name') 的形式,app 代表是应用内 resources 目录中定义的资源;type 表示资源类型,可取值有 color 、 float 、 string 、 string 、 media 等;name 表示资源的文件名字。例如 string.json 中新加 name 为 text_string 的字符串,则访问该字符串资源为 $r('app.string.text_string')。
笔者在 base 目录下新建 float.json 和 color.json 文件,分别存放字体和颜色,资源内容如下图所示:

这里特别注意media下面的文件夹不能在建立文件夹
通过 $('app.type.name') 访问资源的简单样例如下所示:
@Entry @Component struct ResourceTest {
build() {
Column({space: 10}) {
Text($r('app.string.text_string')) // 访问字符串资源
.size({width: 300, height: 120}) // 设置尺寸
.fontSize($r('app.float.text_size')) // 访问字体大小
.fontColor($r('app.color.text_color')) // 访问字体颜色
.backgroundImage($r('app.media.test'), ImageRepeat.XY) // 设备背景图片
}
.width('100%')
.height('100%')
.padding(10)
}
}样例运行结果如下图所示:

访问系统资源
系统资源包含 颜色 、 圆角 、 字体 、 间距 、 字符串 及 图片 等,通过使用系统资源,不同的开发者可以开发出具有相同视觉风格的应用,开发者可以通过 $r('sys.type.name') 的形式引用系统资源,和访问应用资源不同的是使用 sys 代表系统资源,其它和访问应用资源规则一致。
访问系统资源简单样例如下所示:
@Entry
@Component
struct ResourceTest {
build() {
Column() {
Text('Hello')
.fontColor($r('sys.color.ohos_id_color_emphasize'))
.fontSize($r('sys.float.ohos_id_text_size_headline1'))
.fontFamily($r('sys.string.ohos_id_text_font_family_medium'))
.backgroundColor($r('sys.color.ohos_id_color_palette_aux1'))
Image($r('sys.media.ohos_app_icon'))
.border({
color: $r('sys.color.ohos_id_color_palette_aux1'),
radius: $r('sys.float.ohos_id_corner_radius_button'),
width: 2
})
.margin({
top: $r('sys.float.ohos_id_elements_margin_horizontal_m'),
bottom: $r('sys.float.ohos_id_elements_margin_horizontal_l')
})
.height(200)
.width(300)
}
.padding(10)
.width("100%")
.height("100%")
}
}样例运行结果如下图所示:

像素单位
ArkUI 开发框架提供了 4 种像素单位供开发者使用,分别是: px 、 vp 、 fp 和 lpx ,它们之间的区别如下表所示:
| 名称 | 描述 |
|---|---|
| px | 屏幕物理像素单位 |
| vp | 屏幕密度相关像素单位,根据屏幕像素密度转换为屏幕物理像素。 |
| fp | 字体像素,与 vp 类似适用于屏幕密度变化,随系统字体大小设置变化。 |
| lpx | 视窗逻辑像素单位,lpx 单位为实际屏幕宽度与逻辑宽度(在 config.json 中配置的 designWidth )的比值,如配置 designWdith 为 720 时,在实际宽度为 1440 物理像素的屏幕上, 1lpx 为 2px 。 |
- 修改位置如下

ArkUI 开发框架也提供了全局方法把这些不同的尺寸单位相互转换,全局方法如下所示:
declare function vp2px(value: number): number;
declare function px2vp(value: number): number;
declare function fp2px(value: number): number;
declare function px2fp(value: number): number;
declare function lpx2px(value: number): number;
declare function px2lpx(value: number): number;vp2px:将
vp单位的数值转换为以px为单位的数值。px2vp:将
px单位的数值转换为以vp为单位的数值。fp2px:将
fp单位的数值转换为以px为单位的数值。px2fp:将
px单位的数值转换为以fp为单位的数值。lpx2px:将
lpx单位的数值转换为以px为单位的数值。px2lpx:将
px单位的数值转换为以lpx为单位的数值。
这些单位尺寸具体大小,笔者举个简单样例演示一下:
@Entry
@Component
struct ResourceTest {
build() {
Column() {
Flex({ wrap: FlexWrap.Wrap }) {
Column() {
Text("width(220)")
.width(220)
.height(40)
.backgroundColor(Color.Pink)
.textAlign(TextAlign.Center)
.fontSize('12vp')
}.margin(5)
Column() {
Text("width('220px')")
.width('220px')
.height(40)
.backgroundColor(Color.Pink)
.textAlign(TextAlign.Center)
}.margin(5)
Column() {
Text("width('220vp')")
.width('220vp')
.height(40)
.backgroundColor(Color.Pink)
.textAlign(TextAlign.Center)
.fontSize('12vp')
}.margin(5)
Column() {
Text("width('220lpx') designWidth:720")
.width('220lpx')
.height(40)
.backgroundColor(Color.Pink)
.textAlign(TextAlign.Center)
.fontSize('12vp')
}.margin(5)
Column() {
Text("width(vp2px(220) + 'px')")
.width(vp2px(220) + 'px')
.height(40)
.backgroundColor(Color.Pink)
.textAlign(TextAlign.Center)
.fontSize('12vp')
}.margin(5)
Column() {
Text("fontSize('12fp')")
.width(220)
.height(40)
.backgroundColor(Color.Pink)
.textAlign(TextAlign.Center)
.fontSize('12fp')
}.margin(5)
}
.width('100%')
.height("100%")
}
.width('100%')
.height("100%")
.padding(10)
}
}样例运行结果如下图所示:

国际化
ArkUI 开发框架对多语言的支持比较友好,只需要在 resources 目录下创建对应国家的文件夹,名称对国家简码,例如中国为 zh-CN ,则在 resources 下创建 zh-CN 文件夹,然后在 zh-CN 文件下创建对应的类别文件.如果都没有 他就找的是 basic 文件夹
添加多语言
resources 目录下创建 zh-CN / element 文件夹目录后,添加 string.json 文件:
{
"string": [
{
"name":"username",
"value":"用户名"
}
]
}使用多语言
使用 resources 目录下的资源,ArkUI 开发框架给我们提供了快捷方法:$(),比如要访问 string.json 中的资源,可以简写 $('app.string.name'),
@Entry
@Component struct Index {
build() {
Column({space: 10}) {
Text('多语言测试:')
.fontSize(22)
Text($r("app.string.calculator")) // 使用多语言
.fontSize(22)
}
.padding(10)
.width('100%')
.height('100%')
}
}资源管理器
ArkUI 开发框架在 @ohos.resourceManager 模块里提供了资源管理器 ResourceManager,它可以访问不同的资源,比如获取获取字符串资源,获取设备配置信息等等,resourceManager 模块提供部分 API 如下所示:
declare namespace resourceManager {
// 省略部分代码
export interface ResourceManager {
// 获取字符串资源
getString(resId: number, callback: AsyncCallback<string>): void;
// 获取字符串数组资源
getStringArray(resId: number, callback: AsyncCallback<Array<string>>): void;
// 获取媒体资源
getMedia(resId: number, callback: AsyncCallback<Uint8Array>): void;
// 获取设备信息,比如当前屏幕密度,设备类型是手机还是平板等
getDeviceCapability(callback: AsyncCallback<DeviceCapability>): void;
// 获取配置信息,比如当前屏幕方向密度,当前设备语言
getConfiguration(callback: AsyncCallback<Configuration>): void;
// 释放ResourceManager资源
release();
}
}
export default resourceManager;使用 ResourceManager 之前先调用 getContext(this) 方法获取当前组件的 Context,该 Conetxt 内部定义了一个 ResourceManager 的属性,因此可以直接使用 ResourceManager 的各种 getXXX() 方法获取对应资源, ResourceManager 使用流程如下所示:
引入 resourceManager 模块
import resourceManager from "@ohos.resourceManager";获取 ResourceManager
aboutToAppear() {
// 获取ResourceManager
let manager = getContext(this).resourceManager;
}使用 ResourceManager
manager.getString(0x1000001, (innerError, data) => {
if (data) {
// 获取资源成功
} else {
console.log("error: " + JSON.stringify(innerError));
}
});释放 ResourceManager
this.manager.release();完整样例如下所示:
import resourceManager from '@ohos.resourceManager';
@Entry @Component struct ResourceTest {
@State text_string: string = "";
@State capability: string = "";
@State configuration: string = "";
private resManager: resourceManager.ResourceManager;
build() {
Column({ space: 10 }) {
Text(this.text_string) // 访问字符串资源
.size({ width: 300, height: 120 }) // 设置尺寸
.fontSize($r('app.float.text_size')) // 访问字体大小
.fontColor($r('app.color.text_color')) // 访问字体颜色
.backgroundImage($r('app.media.test')) // 设备背景图片
Text(this.capability) // capability信息
.fontSize(20)
Text(this.configuration) // configuration信息
.fontSize(20)
}
.width('100%')
.height('100%')
.padding(10)
}
aboutToAppear() {
this.resManager = getContext(this).resourceManager;
this.resManager.getStringValue(0x1000001, (innerError, data) => {
if(data) {
this.text_string = data;
} else {
console.log("error: " + JSON.stringify(innerError));
}
})
this.resManager.getDeviceCapability((innerError, deviceCapability) => {
if(deviceCapability) {
this.capability = JSON.stringify(deviceCapability);
}
})
this.resManager.getConfiguration((innerError, configuration) => {
if(configuration) {
this.configuration = JSON.stringify(configuration);
}
})
}
aboutToDisappear() {
this.resManager?.release(); // 释放 ReleaseManager 资源
}
}样例运行结果如下图所示:
