鸿蒙新特性——Image 图片组件详解
一、引言
在移动应用开发中,图片是最常见的视觉元素之一。无论是商品列表中的产品图、社交动态中的用户头像、文章详情中的配图,还是背景装饰和图标展示,图片组件几乎无处不在。然而,图片的呈现并非简单的"加载→显示"——开发者需要处理缩放策略、裁剪形状、透明度、边框装饰、加载状态等数十种细节。
传统开发中,实现"圆角头像 + 边框 + 透明度"这样的组合效果,需要在布局文件中嵌套多层容器(CardView、ShapeableImageView、ClipPath 等),再通过代码设置透明度、缩放模式等属性。当产品需求从"圆形头像"变成"圆角矩形 + 2vp 边框 + 半透明覆盖"时,往往需要修改多处代码。
而 HarmonyOS 提供了 Image 组件——一个功能完备的图片显示组件。它通过链式方法统一了图片的所有视觉属性:.objectFit() 控制缩放策略,.borderRadius() 裁剪圆角,.opacity() 调节透明度,.border() 设置边框样式,.objectRepeat() 处理重复模式。所有这些属性的组合只需在一个 Image 组件上声明即可。
本文通过一个"图片效果展廊"Demo 深入讲解 Image 组件的核心用法:五种缩放模式(Cover/Contain/Fill/None/ScaleDown)各自有什么效果?圆角裁剪如何与边框协同?透明度调节如何与交互联动?以及如何构建一个所见即所得的图片效果预览工具。
阅读完本文,你将能够:
- 使用 Image 组件的 objectFit 属性精确控制图片缩放策略
- 使用 borderRadius 实现圆角裁剪效果
- 使用 opacity 和 border 属性组合控制透明度和边框
- 理解五种缩放模式在不同容器尺寸下的表现差异
- 构建交互式图片效果预览页面
二、Image 组件 API 总览
2.1 构造函数
Image(src: PixelMap | ResourceStr | DrawableDescriptor)
| 参数 | 类型 | 说明 |
|---|---|---|
src |
PixelMap | 像素图对象,适用于相机、相册等动态获取的图片 |
src |
ResourceStr | 资源路径,支持 $r('app.media.xxx') 本地资源和网络 URL |
src |
DrawableDescriptor | Drawable 描述符,适用于自定义绘制场景 |
最常用的形式是 $r('app.media.xxx'),引用 resources/base/media/ 目录下的图片资源。对于网络图片,直接传入 URL 字符串即可。
2.2 核心链式方法
// 缩放模式
.objectFit(value: ImageFit): ImageAttribute
// 图片重复模式(当图片小于容器时)
.objectRepeat(value: ImageRepeat): ImageAttribute
// 图片插值算法(缩放时的平滑策略)
.interpolation(value: ImageInterpolation): ImageAttribute
// 是否与文本同行渲染
.renderMode(value: ImageRenderMode): ImageAttribute
// 同步/异步加载
.syncLoad(value: boolean): ImageAttribute
// 加载成功回调
.onComplete(callback: (event?: { width: number; height: number }) => void): ImageAttribute
// 加载失败回调
.onError(callback: (event?: { componentWidth: number; componentHeight: number }) => void): ImageAttribute
| 方法 | 说明 |
|---|---|
.objectFit(ImageFit) |
设置图片缩放填充策略,5 种可选值 |
.objectRepeat(ImageRepeat) |
图片尺寸小于容器时的平铺方式 |
.interpolation(ImageInterpolation) |
缩放时的插值算法(Low/Medium/High) |
.renderMode(ImageRenderMode) |
渲染模式(Original 原色 / Template 模板色) |
.syncLoad(boolean) |
true 同步加载(快但阻塞),false 异步(默认) |
.onComplete(Callback) |
图片加载成功时触发,可获取实际宽高 |
.onError(Callback) |
图片加载失败时触发 |
通用组件属性(Image 也支持):
| 通用属性 | 说明 |
|---|---|
.width() / .height() |
容器宽度和高度 |
.borderRadius() |
圆角裁剪半径 |
.opacity() |
透明度(0.0 ~ 1.0) |
.border() |
边框样式(宽度、颜色、线型) |
.margin() / .padding() |
外边距和内边距 |
.backgroundColor() |
背景色(透出位置可见) |
.clip() |
是否裁剪溢出内容 |
2.3 ImageFit 五种缩放模式
enum ImageFit {
Cover, // 等比缩放,填满容器,可能裁剪
Contain, // 等比缩放,完整显示,可能留白
Fill, // 拉伸填满容器,可能变形
None, // 不缩放,保持原始尺寸
ScaleDown // 仅当图片大于容器时缩小,不大于时保持原尺寸
}
| 模式 | 缩放方式 | 是否保持比例 | 是否填满容器 | 典型场景 |
|---|---|---|---|---|
| Cover | 等比缩放至短边匹配 | 是 | 是(可能裁剪) | 文章头图、轮播图、背景图 |
| Contain | 等比缩放至长边匹配 | 是 | 否(可能留白) | 商品主图、图片预览、Logo 展示 |
| Fill | 拉伸至容器宽高 | 否 | 是 | 极少使用(变形) |
| None | 不缩放 | 是 | 否 | 图标、装饰元素、小尺寸原图 |
| ScaleDown | 不超过原尺寸的等比缩放 | 是 | 否 | 照片列表缩略图 |
Cover 和 Contain 是最常用的两种模式,它们的核心区别在于"优先级":Cover 优先保证容器被填满(牺牲图片完整性),Contain 优先保证图片完整显示(牺牲容器填满率)。Demo 中的五种模式切换可以直观展示这一差异。
2.4 Image 与通用属性的关系
Image 作为一个基础组件,同时继承了所有通用组件属性。这意味着以下属性链式调用都是合法的:
Image($r('app.media.startIcon'))
.objectFit(ImageFit.Cover) // Image 专有属性
.width(200) // 通用属性——容器宽度
.height(200) // 通用属性——容器高度
.borderRadius(16) // 通用属性——圆角裁剪
.opacity(0.8) // 通用属性——透明度
.border({ // 通用属性——边框
width: 2,
color: '#1677FF',
style: BorderStyle.Solid
})
理解 Image 属性 + 通用属性的组合方式,是用好 Image 组件的关键。objectFit 控制图片内容在容器内的呈现方式,而 borderRadius、opacity、border 控制容器的外观效果。两者协同工作,产生丰富的视觉效果。
三、Demo 设计:图片效果展廊
3.1 功能概述
Demo 是一个"图片效果展廊"应用,让用户通过交互式控件实时预览 Image 组件的各种属性组合效果:
- 主图片预览区:220vp 高度的图片展示区,实时反映所有属性设置的效果
- 五种缩放模式切换:Cover / Contain / Fill / None / ScaleDown 卡片选择器
- 圆角半径调节:预设值(0 / 8 / 16 / 24 / 40 vp)快速切换
- 透明度滑块:0.2 ~ 1.0 范围调节,实时百分比显示
- 边框宽度调节:无边框 / 2vp / 4vp / 6vp 四档选择
- 边框颜色选择:蓝 / 红 / 绿 / 橙 / 紫五种颜色色块选择
- 效果对比网格:五种缩放模式的缩略图同时展示,方便对比
3.2 交互点
| # | 交互 | 说明 |
|---|---|---|
| 1 | 切换缩放模式 | 点击五种模式卡片,主预览图和效果对比同步高亮当前选择 |
| 2 | 调节圆角 | 点击圆角预设值按钮(0/8/16/24/40),图片实时裁剪为对应圆角 |
| 3 | 调节透明度 | 拖动透明度滑块(0.2~1.0),图片和百分比读数同步变化 |
| 4 | 设置边框 | 切换边框宽度 + 颜色,边框样式实时反映到图片容器 |
| 5 | 效果对比浏览 | 底部 Flex 网格同时展示五种模式缩略图,点击可跳转到对应模式 |
四、完整代码实现

4.1 数据模型与状态
interface StyleOption {
label: string;
fit: ImageFit;
desc: string;
}
@State selectedFit: number = 0;
@State imgBorderRadius: number = 0;
@State imgBorderWidth: number = 0;
@State imgBorderColor: string = '#1677FF';
@State imgOpacity: number = 1.0;
private fitOptions: StyleOption[] = [
{ label: 'Cover', fit: ImageFit.Cover, desc: '等比缩放填满,可能裁剪' },
{ label: 'Contain', fit: ImageFit.Contain, desc: '等比缩放完整显示' },
{ label: 'Fill', fit: ImageFit.Fill, desc: '拉伸填满,可能变形' },
{ label: 'None', fit: ImageFit.None, desc: '原始尺寸,不缩放' },
{ label: 'ScaleDown', fit: ImageFit.ScaleDown, desc: '仅缩小,不放大' }
];
每个缩放模式包含三个字段:label(显示名称)、fit(ImageFit 枚举值)、desc(中文描述)。五个 @State 变量分别控制主预览图的缩放模式、圆角大小、边框宽度、边框颜色和透明度。注意变量名不能使用 borderRadius、opacity 等,因为它们会与组件的链式方法名冲突。
4.2 主图片预览区
Column() {
Image($r('app.media.startIcon'))
.objectFit(this.fitOptions[this.selectedFit].fit)
.width('100%')
.height(220)
.borderRadius(this.imgBorderRadius)
.opacity(this.imgOpacity)
.border({
width: this.imgBorderWidth,
color: this.imgBorderColor,
style: BorderStyle.Solid
})
Text(this.fitOptions[this.selectedFit].label.concat(' — ',
this.fitOptions[this.selectedFit].desc))
.fontSize(12)
.fontColor('#9999AA')
.margin({ top: 12 })
}
逐行解析:
$r('app.media.startIcon'):引用本地资源图片.objectFit(...):通过this.selectedFit索引到对应的ImageFit枚举值,实现动态切换.height(220):固定高度 220vp,宽度撑满('100%'),形成宽高比约 1.6:1 的横向容器.borderRadius(this.imgBorderRadius):动态圆角半径,从 0(直角)到 40(大圆角).opacity(this.imgOpacity):动态透明度,从 0.2(几乎透明)到 1.0(完全可见).border({...}):边框对象,包含宽度、颜色和线型(BorderStyle.Solid实线)- 预览图下方显示当前缩放模式的名称和描述
4.3 缩放模式选择器
ForEach(this.fitOptions, (opt: StyleOption, idx: number) => {
Row() {
Column() {
Text(opt.label)
.fontSize(14)
.fontColor(this.selectedFit === idx ? '#FFFFFF' : '#1a1a2e')
.fontWeight(this.selectedFit === idx ? FontWeight.Bold : FontWeight.Normal)
Text(opt.desc)
.fontSize(11)
.fontColor(this.selectedFit === idx ? '#FFFFFF88' : '#BBBBCC')
.margin({ top: 2 })
}
.alignItems(HorizontalAlign.Start)
.layoutWeight(1)
if (this.selectedFit === idx) {
Text('✓')
.fontSize(16)
.fontColor('#FFFFFF')
.fontWeight(FontWeight.Bold)
}
}
.width('100%')
.padding({ top: 12, bottom: 12, left: 14, right: 14 })
.borderRadius(10)
.backgroundColor(this.selectedFit === idx ? '#1677FF' : '#FAFBFC')
.margin({ bottom: 8 })
.onClick(() => { this.selectedFit = idx; })
})
每个模式项是一个 Row,包含左侧的文字说明和右侧的选中标记(✓)。选中项使用蓝色背景 + 白色文字,未选中项使用浅灰色背景 + 深色文字。这种高对比度的视觉反馈让用户清晰地知道当前选中的模式。ForEach 遍历 fitOptions 数组,每个项绑定 onClick 将 selectedFit 设为对应索引。
4.4 圆角半径调节
Row() {
Text('圆角')
.fontSize(14)
.fontColor('#1a1a2e')
.fontWeight(FontWeight.Medium)
.width(48)
Row() {
ForEach([0, 8, 16, 24, 40], (r: number) => {
Text(r.toString())
.fontSize(12)
.fontColor(this.imgBorderRadius === r ? '#FFFFFF' : '#1a1a2e')
.fontWeight(this.imgBorderRadius === r ? FontWeight.Bold : FontWeight.Normal)
.padding({ top: 4, bottom: 4, left: 10, right: 10 })
.borderRadius(10)
.backgroundColor(this.imgBorderRadius === r ? '#1677FF' : '#F2F3F5')
.margin({ left: 6 })
.onClick(() => { this.imgBorderRadius = r; })
})
}
}
圆角预设值覆盖了从直角(0vp)到大圆角(40vp)的常用范围:0vp 直角适合信息图表的原样展示,8vp 微圆角普遍用于卡片内容,16vp 标准圆角适合中等尺寸图片,24vp 和 40vp 大圆角接近头像效果。数值直接标注在按钮上,用户无需记忆。
4.5 透明度滑块
Row() {
Text('透明度')
.fontSize(14)
.fontColor('#1a1a2e')
.fontWeight(FontWeight.Medium)
.width(48)
Slider({
value: this.imgOpacity,
min: 0.2,
max: 1.0,
step: 0.1,
style: SliderStyle.OutSet
})
.blockColor('#1677FF')
.trackColor('#F0F0F0')
.selectedColor('#1677FF')
.layoutWeight(1)
.onChange((value: number) => { this.imgOpacity = value as number; })
Text((this.imgOpacity * 100).toFixed(0).concat('%'))
.fontSize(12)
.fontColor('#9999AA')
.fontFamily('monospace')
.width(36)
.textAlign(TextAlign.End)
}
Slider 范围设置为 0.2 ~ 1.0,因为低于 0.2 的透明度下图片几乎不可见,实际意义不大。步进值 0.1 提供 9 档精细调节。右侧百分比读数使用 toFixed(0) 取整显示(如 80%),字体使用 monospace 等宽字体避免数字跳变时的宽度抖动。
4.6 边框宽度与颜色选择
// 边框宽度
ForEach([0, 2, 4, 6], (w: number) => {
Text(w === 0 ? '无' : w.toString().concat('vp'))
.fontSize(12)
.fontColor(this.imgBorderWidth === w ? '#FFFFFF' : '#1a1a2e')
.fontWeight(this.imgBorderWidth === w ? FontWeight.Bold : FontWeight.Normal)
.padding({ top: 4, bottom: 4, left: 8, right: 8 })
.borderRadius(10)
.backgroundColor(this.imgBorderWidth === w ? '#1677FF' : '#F2F3F5')
.margin({ left: 6 })
.onClick(() => { this.imgBorderWidth = w; })
})
// 边框颜色
ForEach(['#1677FF', '#FF4D4F', '#52C41A', '#FF9800', '#9C27B0'], (c: string) => {
Row()
.width(24)
.height(24)
.borderRadius(12)
.backgroundColor(c)
.margin({ left: 8 })
.border({ width: this.imgBorderColor === c ? 3 : 0, color: c })
.onClick(() => { this.imgBorderColor = c; })
})
边框宽度提供四档:0vp(无边框)、2vp(细边框)、4vp(中等)、6vp(粗边框),覆盖了从无到突出的需求范围。边框颜色提供五种选项,以圆形色块形式展示(24x24 圆形),选中的色块叠加 3vp 同色边框作为选中标记——这是一种比文字标记更直观的"所见即所得"交互。
4.7 效果对比网格
Flex({ wrap: FlexWrap.Wrap }) {
ForEach(this.fitOptions, (opt: StyleOption, idx: number) => {
Column() {
Image($r('app.media.startIcon'))
.objectFit(opt.fit)
.width(68)
.height(68)
.borderRadius(12)
.border({ width: 0.5, color: '#F0F0F0' })
.margin({ bottom: 6 })
Text(opt.label)
.fontSize(10)
.fontColor('#9999AA')
}
.margin({ right: 10, bottom: 12 })
.alignItems(HorizontalAlign.Center)
.onClick(() => { this.selectedFit = idx; })
})
}
.width('100%')
使用 Flex({ wrap: FlexWrap.Wrap }) 实现自动换行网格布局。每格包含一个 68x68vp 的缩略图(应用对应缩放模式)和下方模式名称。所有缩略图同时展示,用户可以直观对比同一张图片在五种缩放模式下的呈现差异。点击缩略图可切换主预览图的缩放模式——这是一个"详情↔概览"的双向联动设计。
五、关键技术点详解
5.1 objectFit 五种模式的视觉差异
ImageFit 的五种模式本质上是在回答一个问题:当图片的原始宽高比与容器的宽高比不一致时,图片应该如何适应容器?
假设原图尺寸为 800×600(宽高比 4:3),容器尺寸为 360×220(宽高比约 1.64:1)。容器比图片更"扁"——这是移动端图片展示中最常见的场景。
Cover(等比缩放填满):图片等比缩放,使短边完全覆盖容器。对于 4:3 的图片放入 1.64:1 的容器,图片先缩放至宽度 360px,此时高度为 270px(360×3/4),超出容器高度 220px。超出的 50px(上下各 25px)被裁剪。结果是容器被完全填满,但图片顶部和底部各损失约 11% 的内容。
Contain(等比缩放完整显示):图片等比缩放,使长边恰好贴合容器。对于上述例子,图片先缩放至高度 220px,此时宽度为 293px(220×4/3),小于容器宽度 360px。左右各留白约 33px。结果是图片完整可见,但容器两侧有留白区域(背景色透出)。
Fill(拉伸填满):图片的宽度拉伸至 360px,高度拉伸至 220px,不保持原始宽高比。结果是容器被完全填满、无留白、无裁剪——但图片会发生变形。4:3 的原图被拉伸为 1.64:1,画面元素被横向拉长。
None(原始尺寸):图片保持 800×600 的原始尺寸,不做任何缩放。由于原图远大于 360×220 的容器,将按容器左上角对齐,只显示图片的左上角部分(约 360×220 区域),其余内容不可见。
ScaleDown(仅缩小):如果图片大于容器,等比缩小至 Contain 的状态;如果图片小于或等于容器,保持原始尺寸(类似 None)。对于 800×600 的图放入 360×220 的容器,效果等同于 Contain。但对 100×80 的小图放入同一容器,效果等同于 None(保持原尺寸,不放大)。
5.2 borderRadius 的裁剪机制
.borderRadius() 在 Image 组件上的行为与普通容器一致——它以容器的边界矩形为参考,对四个角进行圆角裁剪。但需要注意的是,裁剪发生在 objectFit 缩放之后。
也就是说,渲染顺序为:原图加载 → objectFit 缩放 → borderRadius 裁剪 → opacity 透明度 → border 边框绘制。理解这个顺序对于组合效果很重要。例如,当 objectFit 为 Cover 且 borderRadius 为 40vp 时,图片先被切割适配容器宽高比,再被裁剪为圆角矩形——这意味着裁剪线的位置取决于容器边界,不会受图片缩放偏移的影响。
一个实践中常见的坑:给 Cover 模式的图片设置大圆角时,四角会因为裁剪而显露容器背景色。解决方案是同时给 Image 组件设置与裁剪背景协调的 .backgroundColor()。
5.3 opacity 与图片叠加效果
.opacity() 设置的是整个 Image 组件(包括图片内容和边框)的透明度。它常用于以下场景:
- 加载态过渡:图片加载完成后从 opacity:0 渐显到 opacity:1
- 禁用/离线状态:将图片 opacity 降低至 0.4~0.5,表示该内容当前不可用
- 叠加文字的背景图:图片 opacity 设置为 0.3~0.6,避免干扰上方白色文字的阅读
- 预览遮罩效果:将主图 opacity 设为 0.8,营造柔和视觉效果
Demo 中的 Slider 范围 0.2~1.0 涵盖了从"几乎透明"到"完全不透明"的区间。在实际产品中,低于 0.3 的透明度会使图片辨识度大幅下降,通常仅用于背景装饰目的。
5.4 border 边框的组成与边角处理
.border() 接收一个 BorderOptions 对象,包含三个属性:
interface BorderOptions {
width: EdgeWidths | Length; // 边框宽度
color: EdgeColors | ResourceColor; // 边框颜色
style: BorderStyle; // 线型(Solid/Dashed/Dotted)
radius?: BorderRadiuses | Length; // 边框自身的圆角(与容器 borderRadius 独立)
}
border 绘制在 borderRadius 裁剪之后,因此边框会沿着圆角容器的边缘绘制,呈现出平滑的圆角边框效果。这也是 Demo 中 border 与 borderRadius 组合使用效果良好的原因。
需要注意的是,border.width 会影响容器的总体尺寸——4vp 的边框会使容器在每个方向上增加 4vp(总宽高各增加 8vp)。在紧凑布局中,边框宽度需要考虑对整体布局的影响。
5.5 图片加载性能考量
对于列表场景(如商品列表、社交动态流),大量 Image 组件的加载性能直接影响滑动流畅度和用户体验:
-
本地资源 vs 网络加载:
$r('app.media.xxx')引用的本地资源加载速度远快于网络图片。对于列表中的固定装饰图标,始终使用本地资源。 -
同步 vs 异步加载:
.syncLoad(true)强制同步加载图片(阻塞渲染线程),仅适用于首屏关键图片(如启动页背景)。.syncLoad(false)(默认)异步加载,不会阻塞 UI 线程——绝大多数场景下使用默认异步加载即可。 -
图片尺寸:加载 2000×1500 的原图显示在 100×75 的缩略图中,不仅浪费内存,还可能导致缩放卡顿。实践中推荐在服务端提供多尺寸裁剪的图片,或者使用 ArkUI 的图片解码尺寸限制。
-
插值算法:
.interpolation(ImageInterpolation.Low)使用低质量插值(最近邻),适合需要快速展示的缩略图列表;.interpolation(ImageInterpolation.High)使用高质量插值(双三次),适合图片详情页的大图展示。默认值为.Medium,平衡了质量和性能。
5.6 图片容器的层级叠加
在实际开发中,很少单纯使用一个图片组件——更常见的是在图片上叠加文字、图标、蒙层等元素。Image 组件支持通过 Stack 容器实现这种叠加效果:
Stack() {
Image($r('app.media.startIcon'))
.objectFit(ImageFit.Cover)
.width('100%')
.height(200)
.borderRadius(16)
Column() {
Text('推荐标题')
.fontSize(18)
.fontColor('#FFFFFF')
.fontWeight(FontWeight.Bold)
Text('副标题说明')
.fontSize(12)
.fontColor('#FFFFFFCC')
}
.width('100%')
.padding(16)
.alignItems(HorizontalAlign.Start)
}
.position({ bottom: 0 }) // 文字叠加在底部
Stack 将图片放在底层,文字放在顶层,通过 .position() 或 .align() 控制文字在图片上的位置。加上 .borderRadius() 的裁剪,文字不会超出圆角边界。
六、运行效果
6.1 初始状态
进入"图片效果展廊"页面,顶部是深色标题栏显示"图片效果展廊"。下方白色信息卡片介绍 Image 组件的基本概念。主预览区(220vp 高度)默认以 Cover 模式展示图片,圆角为 0vp、透明度 100%、无边框。预览图下方显示"Cover — 等比缩放填满,可能裁剪"。底部效果对比网格以 Flex 布局展示五种模式的缩略图(68×68vp),Cover 带高亮标记。
6.2 切换缩放模式
点击"Contain"模式卡片 → 卡片变为蓝色背景 + 白色文字 + ✓ 标记。主预览图立即切换为 Contain 模式:图片等比缩放至完整显示,容器两侧出现留白(背景色可见)。效果对比网格中 Contain 缩略图也同步变化。依次点击 Fill / None / ScaleDown 可观察填满拉伸、原尺寸裁剪、仅缩小不放大等不同效果。
6.3 调节圆角与边框
点击圆角预设 24vp → 主预览图四角变为大圆角裁切,图片内容在圆角边界被裁剪为圆润形态。效果对比网格中的缩略图保持 12vp 固定圆角不变(网格缩略图不受主预览配置影响)。
点击边框宽度 4vp → 主预览图外围出现 4vp 宽度的蓝色(默认色)实线边框。边框沿圆角边缘平滑绘制。切换边框颜色为橙色(#FF9800)→ 色块出现选中标记,预览图边框颜色从蓝色变为橙色。
6.4 调节透明度
拖动透明度滑块至 60% → 主预览图透明度降低为 0.6,图片内容显著变淡。右侧百分比读数从"100%“变为"60%”。继续拖动至 20% → 图片几乎透明,仅能隐约看到轮廓。滑块回到 100% → 图片恢复完全不透明。
6.5 组合效果
将多个属性组合使用:缩放模式设为 Cover、圆角 40vp、边框宽度 4vp、边框颜色紫色(#9C27B0)、透明度 90% → 主预览图呈现为大圆角、细紫边框、略柔和的大图效果。这种"所见即所得"的预览方式,让设计人员可以在代码层面精确控制图片的最终视觉效果。
七、总结
本文通过一个"图片效果展廊"实战 Demo,深入讲解了 HarmonyOS Image 组件的核心用法:
-
objectFit 五种模式:Cover(填满裁剪)、Contain(完整显示)、Fill(拉伸变形)、None(原尺寸)、ScaleDown(仅缩小)。理解"图片宽高比 vs 容器宽高比"的匹配逻辑是正确使用缩放模式的前提。
-
borderRadius 圆角裁剪:在 objectFit 缩放之后执行,以容器边界为参考进行四角裁剪。可配合 backgroundColor 处理裁剪区域的背景色。
-
opacity 透明度:调节整个 Image 组件(内容+边框)的透明度,常用于加载过渡、禁用状态、背景遮罩等场景。
-
border 边框:沿 borderRadius 裁剪后的容器边缘绘制,支持宽度、颜色、线型的灵活组合。
-
通用属性组合:Image 专有属性(objectFit)与通用属性(borderRadius/opacity/border)协同工作,通过"缩放→裁剪→透明→描边"的渲染顺序产生丰富的视觉效果。
Image 是 ArkUI 中使用频率最高的组件之一。从简单的图标展示到复杂的图片列表,从静态的装饰元素到交互动效的视觉载体,Image 组件以简洁的 API 覆盖了所有图片显示场景。希望本文能帮助你在实际项目中灵活运用 Image 组件的各项能力。
本文基于 HarmonyOS NEXT API 24 编写,代码经 DevEco Studio 6.1.1 编译验证通过。
更多推荐


所有评论(0)