目录
一、前置知识
1、Resources目录
Resources目录用于统一存放应用所需的各种资源,包括图片、音频、视频、文本等等。下面简要介绍 resources 目录的用法,首先需要了解 resources 的目录结构:
resources 目录下,可能存在base、(zh_CN和en_US)、系统主题(dark和light)、设备类型(phone 和 tablet)和 rawfile 等适配不同的环境的不同版本的目录。其中 zh_CN和en_US目录都包含 element、media、profile文件夹。
我们可以为上述每种环境各自准备一套资源文件,每种环境对应 resources 下的一个目录,例如上述的 zh_CN 和 en_US。我们在使用resources下的资源时,无需指定具体的环境版本,系统会根据设备所处的环境自动选择匹配的版本,例如当设备系统语言为中文时,则会使用zh_CN目录下的资源,为英文时,则会使用en_US目录下的资源。若没有与当前所处环境相对应的版本,则使用 base 目录下资源。
各目录存储的具体资源如下
- media
存放媒体资源,包括图片、音频、视频等文件。
- element
存放用于描述页面元素的尺寸、颜色、样式等的各种类型的值,每种类型的值都定义在一个相应的 JSON 文件中。
- profile
存放自定义配置文件。
- rawfile
用于存储任意格式的原始文件,需要注意的是rawfile不会根据设备所处的环境去匹配不同的资源。
2、屏幕参数
大家先掌握屏幕相关的几个参数:
- 尺寸: 屏幕对角线的长度,以英寸(
inches
)为单位。 - 像素: 屏幕显示的最小单位,屏幕上的一个小亮点称为一个像素。单词Pixel,简写 px
- 分辨率: 屏幕上横向和纵向的像素数量。
- 像素密度: 像素密度是每英寸屏幕上的像素数量,通常以
PPI
(Pixels Per Inch)表示,计算公式如下。
关系:像素密度高 -- > 每英寸屏幕像素多 --> 画质细腻
像素密度低 -- > 每英寸屏幕像素少 --> 画质粗糙
○ px(Pixel)
物理像素,以像素个数来定义图像尺寸。这种方式的弊端是,在不同像素密度的屏幕上,相同的像素个数对应的物理尺寸是不同的。这样一来就会导致我们的应用在不同设备上显示的尺寸可能不同。如下图所示
○ vp(Virtual Pixel)
为了保证一致的观感,我们可以使用虚拟像素作为单位。虚拟像素是一种可根据屏幕像素密度灵活缩放的单位。1vp相当于像素密度为160ppi的屏幕上的1px。在不同像素密度的屏幕上,HarmonyOS会根据如下公式将虚拟像素换算为对应的物理像素
根据上述公式,不难看出,使用虚拟像素作为单位时,同一尺寸:
- 像素密度低---> 屏幕物理像素少--->单个像素的物理尺寸大
- 像素密度高---> 屏幕物理像素多--->单个像素的物理尺寸小
因此就能在不同像素密度的屏幕上,获得基本一致的观感了。如下图所示
二、图片组件参数
Image组件的参数类型为string | Resource | media.PixelMap。
1、string类型
string 本地图片路径和网络图片网址
- 本地图片: Image('images/demo.jpg')
注意:使用这种方式引入本地图片,需要将图片置于ets目录下,并且需要为Image组件提供图片相对于ets目录的路径。
- 网络图片: Image('http://xxx/xxx.jpg')
注意:真机中运行的鸿蒙应用,访问网络图片需要配置网络访问权限,不过在预览器和模拟器中测试时不受限制。
2、Resource类型
Resource类型的参数用于引入 resources 目录下的图片。resources目录下可用于存放图片的目录有resources/*/media 以及 resources/rawfile,两个目录下图片的使用方式有所不同。
- media目录
使用$r('app.media.<filename>')
的方式引用
@Entry
@Component
struct Index {
@State isOn: boolean = false;
@State isDel: boolean = false;
build() {
Column({ space: 10 }) {
if (this.isOn) {
Image($r('app.media.img_light001')).width(300).height(300);
} else {
Image($r('app.media.img_dark001')).width(300).height(300);
}
Row({ space: 20 }) {
Button('关灯')
.onClick(() => {
this.isOn = false;
});
Button('开灯')
.onClick(() => {
this.isOn = true;
});
}
}
.width('100%')
.height("100%")
.justifyContent(FlexAlign.Center)
}
}
- rawfile目录
使用 $rawfile('path/to/your/file')
@Entry
@Component
struct Index {
@State isOn: boolean = false;
@State isDel: boolean = false;
build() {
Column({ space: 10 }) {
if (this.isOn) {
Image($rawfile('img_light001.jpg')).width(300).height(300);
} else {
Image($rawfile('img_dark001.jpg')).width(300).height(300);
}
Row({ space: 20 }) {
Button('关灯')
.onClick(() => {
this.isOn = false;
});
Button('开灯')
.onClick(() => {
this.isOn = true;
});
}
}
.width('100%')
.height("100%")
.justifyContent(FlexAlign.Center)
}
}
3、media.PixelMap类型(了解)
PixelMap指的是图片的像素位图,其通常是一个二维数组,数组中的每个元素对应着图片中的一个像素,其包含了该像素的颜色等信息。像素位图主要用于图片编辑的场景,例如、
三、图片组件常用属性
1、图片尺寸
图片尺寸可通过width()
方法和height()
方法进行设置。
width()
方法和height()
参数类型均为:string | number | Resource
1.1、string类型
string类型的参数可为百分比,例如'100%',或者为具体尺寸,例如'100px'。
1.2、number类型
number类型的参数,默认以vp作为单位。
1.3、Resource类型
Resource类型参数用于引用 resources下的element目录中定义的数值。每种类型的值分别定义在一个JSON文件中。文件中的内容为键值对(name-value)的形式。具体内容如下:
element/string.json
{
"string": [
{
"name": "module_desc",
"value": "模块描述"
},
{
"name": "greeting",
"value": "你好"
}
]
}
element/integer.json
{
"integer": [
{
"name": "width",
"value": 150
},
{
"name": "height",
"value": 150
}
]
}
使用方式 $r('app.<data_type>.<name>')
2、图片缩放
当图片的原始大小与Image组件不同时,可通过objectFit()
方法来设置图片的显示效果。该方法的参数类型为ImageFit
枚举类型,可选的枚举值如下:
@Entry
@Component
struct ImageObjectFit {
build() {
Column({ space: 20 }) {
Column() {
Image($r('app.media.img_harmony'))
.width('720px')
.height('334px')
Text('原图')
}
Row({ space: 20 }) {
Column() {
Image($r('app.media.img_harmony'))
.width('450px')
.height('450px')
.borderWidth(1)
.objectFit(ImageFit.None)
Text('None')
}
Column() {
Image($r('app.media.img_harmony'))
.width('450px')
.height('450px')
.borderWidth(1)
.objectFit(ImageFit.Contain)
Text('Contain')
}
}
Row({ space: 20 }) {
Column() {
Image($r('app.media.img_harmony'))
.width('450px')
.height('450px')
.borderWidth(1)
.objectFit(ImageFit.Cover)
Text('Cover')
}
Column() {
Image($r('app.media.img_harmony'))
.width('450px')
.height('450px')
.borderWidth(1)
.objectFit(ImageFit.Fill)
Text('Fill')
}
}
Row({ space: 20 }) {
Column() {
Image($r('app.media.img_harmony'))
.width('450px')
.height('450px')
.borderWidth(1)
.objectFit(ImageFit.ScaleDown)
Text('ScaleDown')
}
Column() {
Image($r('app.media.img_harmony'))
.width('450px')
.height('450px')
.borderWidth(1)
.objectFit(ImageFit.Auto)
Text('Auto')
}
}
}
.justifyContent(FlexAlign.Center)
.width('100%')
.height('100%')
}
}
3、图片插值
当原图分辨率较低并且需要放大显示时,图片会模糊并出现锯齿。如下图所示
这时可以使用interpolation()
方法对图片进行插值,使图片显示得更清晰。该方法的参数为ImageInterpolation
枚举类型,可选的值有
@Entry
@Component
struct ImageInterpolationPage {
build() {
Column({ space: 50 }) {
Row({ space: 20 }) {
Column() {
Image($r('app.media.img_flower'))
.width('500px')
.height('500px')
.interpolation(ImageInterpolation.None)
Text('None')
}
Column() {
Image($r('app.media.img_flower'))
.width('500px')
.height('500px')
.interpolation(ImageInterpolation.Low)
Text('Low')
}
}
Row({ space: 20 }) {
Column() {
Image($r('app.media.img_flower'))
.width('500px')
.height('500px')
.interpolation(ImageInterpolation.Medium)
Text('Medium')
}
Column() {
Image($r('app.media.img_flower'))
.width('500px')
.height('500px')
.interpolation(ImageInterpolation.High)
Text('High')
}
}
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
}