# 2.3:资源管理

本节笔者向读者介绍一下 OpenHarmony 应用的资源分类和资源的访问以及应用开发使用的像素单位以及各单位之间相互转换的方法。

# 2.3.1:资源分类

移动端应用开发常用到的资源比如图片,音视频,字符串等都有固定的存放目录,OpenHarmony 把这些应用的资源文件统一放在 resources 目录下的各子目录中便于开发者使用和维护, resoures 目录包括两大类,一类为 base 目录与限定词目录,另一类为 rawfile 目录。新建 OpenHarmony 应用,默认生成的资源目录如下所示:

2_3_1_1

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

2_3_1_2

# 2.3.2:资源访问

OpenHarmony 应用资源分为两类,一类是应用资源,另一类是系统资源,它们的资源访问方式如下:

  • 访问应用资源

    base 目录下的资源文件会被编译成二进制文件并且给这些资源赋予唯一的 ID ,使用相应资源的时候通过资源访问符 $r('app.type.name') 的形式,app 代表是应用内 resources 目录中定义的资源;type 表示资源类型,可取值有 colorfloatstringstringmedia 等;name 表示资源的文件名字。例如 string.json 中新加 nametext_string 的字符串,则访问该字符串资源为 $r('app.string.text_string')

    笔者在 base 目录下新建 float.jsoncolor.json 文件,分别存放字体和颜色,资源内容如下图所示:

    2_3_2_1

    通过 $('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)
      }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14

    样例运行结果如下图所示:

    2_3_2_2
  • 访问系统资源

    系统资源包含 颜色圆角字体间距字符串图片 等,通过使用系统资源,不同的开发者可以开发出具有相同视觉风格的应用,开发者可以通过 $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%")
      }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26

    样例运行结果如下图所示:

    2_3_2_3

# 2.3.3:像素单位

ArkUI开发框架提供了 4 种像素单位供开发者使用,分别是: pxvpfplpx ,它们之间的区别如下表所示:

名称 描述
px 屏幕物理像素单位。
vp 屏幕密度相关像素单位,根据屏幕像素密度转换为屏幕物理像素。
fp 字体像素,与vp类似适用于屏幕密度变化,随系统字体大小设置变化。
lpx 视窗逻辑像素单位,lpx单位为实际屏幕宽度与逻辑宽度(在 config.json 中配置的 designWidth )的比值,如配置 designWdith 为 720 时,在实际宽度为 1440 物理像素的屏幕上, 1px 为 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;
1
2
3
4
5
6
  • 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)
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65

样例运行结果如下图所示:

2_3_3_1

# 2.3.4:资源管理器

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;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

使用 ResourceManager 之前先调用 getContext(this) 方法获取当前组件的 Context,该 Conetxt 内部定义了一个 ResourceManager 的属性,因此可以直接使用 ResourceManager 的各种 getXXX() 方法获取对应资源, ResourceManager 使用流程如下所示:

  • 引入 resourceManager

    import resourceManager from '@ohos.resourceManager';
    
    1
  • 获取 ResourceManager

    aboutToAppear() {
      // 获取ResourceManager
      let manager = getContext(this).resourceManager;
    }
    
    1
    2
    3
    4
  • 使用 ResourceManager

    manager.getString(0x1000001, (innerError, data) => {
      if(data) {
        // 获取资源成功
      } else {
        console.log("error: " + JSON.stringify(innerError))
      }
    })
    
    1
    2
    3
    4
    5
    6
    7
  • 释放 ResourceManager

    this.manager.release();
    
    1

完整样例如下所示:

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 资源
  }

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57

样例运行结果如下图所示:

2_3_4_1

📢:渲染出来的 mock string 是因为在预览器上暂时不支持 ResourceManager 的用法,在实际设备上是没问题的。

(adsbygoogle = window.adsbygoogle || []).push({});
请作者喝杯咖啡

津公网安备 12011402001367号

津ICP备2020008934号-2

中央网信办互联网违法和不良信息举报中心

天津市互联网违法和不良信息举报中心