HarmonyOS实战《疆域纪行》第08篇|资源与启动体验:本地图片、启动页和视觉一致性优化
这一篇不讲业务逻辑,专门讲“看起来像不像成品”。旅行 App 很吃图片和启动体验:资源命名、图片裁切、渐变遮罩、启动窗口背景和应用内启动页,都会影响用户第一印象。
项目落点:
- 图片资源:
entry/src/main/resources/base/media - 启动窗口:
entry/src/main/module.json5 - 启动背景色:
entry/src/main/resources/base/element/color.json - 应用内启动页:
LaunchSplash() - 图片展示:
ImageFit.Cover、主题色兜底、渐变层
读完这一篇,你可以复用一套离线图片管理思路:图片走资源系统,数据层保存 Resource,UI 层统一裁切和遮罩,启动体验保持前后一致。
本文解决什么
- 把本地图片放进资源系统,避免页面拼文件路径。
- 让启动窗口背景、应用内启动页和首屏色调保持一致,减少冷启动跳变。
- 用主题色、Cover 裁切和渐变遮罩统一不同来源图片的观感。
旅行 App 的一半体验在图片
旅行攻略应用和普通工具应用最大的区别,是图片非常重要。
《疆域纪行》内置了大量本地图片资源:
entry/src/main/resources/base/media/
├── img_kanas.jpg
├── img_sayram.jpg
├── img_duku.jpg
├── img_kashgar_oldtown.jpg
├── img_dapanji.jpg
├── splash_fullscreen.jpg
├── splash_poster.png
├── startIcon.png
└── ...
这些图片覆盖了景点、美食、路线、启动页和图标。对离线 App 来说,本地资源管理就是产品体验的一部分。
图片资源如何引用
在数据层,图片通过 Resource 引用:
image: $r('app.media.img_sayram')
模型中对应字段是:
image: Resource;
这让数据和 UI 之间的关系非常直接。页面组件不需要拼路径,也不需要关心图片文件名,只要消费 item.image。
例如卡片里:
Image(item.image)
.width('100%')
.height(150)
.objectFit(ImageFit.Cover)
详情页头图里:
this.DetailHero(item.color, item.image)
这就是把资源引用纳入数据模型的好处。
启动页:不要让冷启动像白屏
项目自己做了应用内启动页:
@State showLaunchSplash: boolean = true;
build() 里先判断:
if (this.showLaunchSplash) {
this.LaunchSplash()
} else {
this.MainShell()
}
启动页组件:
@Builder
LaunchSplash() {
Image($r('app.media.splash_fullscreen'))
.width('100%')
.height('100%')
.objectFit(ImageFit.Cover)
.backgroundColor('#071D32')
.onAppear(() => {
setTimeout(() => {
this.showLaunchSplash = false;
}, 1800);
})
}
这里用一张全屏图片做过渡,1.8 秒后进入主页面。
对内容型 App 来说,启动页有两个作用:
- 让品牌和场景先出现。
- 避免图片资源加载时的突兀空白。
不过要注意,应用内启动页不宜过长。用户不是来看广告的,1-2 秒足够。
系统启动窗口配置
除了应用内启动页,module.json5 里还有系统启动窗口配置:
"startWindowIcon": "$media:startIcon",
"startWindowBackground": "$color:start_window_background"
颜色定义在:
{
"color": [
{
"name": "start_window_background",
"value": "#071D32"
}
]
}
这里的背景色和应用内启动页保持一致。这样从系统启动窗口到 App 首屏,视觉不会跳变。
图片裁切:统一用 Cover
项目中大部分图片展示都使用:
.objectFit(ImageFit.Cover)
它的作用是让图片填满容器,超出部分裁切。
旅行素材的比例经常不同:
- 景点横图
- 美食近景
- 城市街区图
- 路线封面图
如果直接等比完整显示,卡片高度会不稳定;如果强行拉伸,图片会变形。Cover 是列表卡片和头图里最稳的选择。
用主题色兜底图片观感
许多卡片先放主题色,再叠加图片:
Column()
.width('100%')
.height(150)
.backgroundColor(item.color)
Image(item.image)
.width('100%')
.height(150)
.objectFit(ImageFit.Cover)
.opacity(0.55)
这样做有三个好处:
- 图片未加载前不会是纯白空块。
- 不同图片在透明度叠加后更统一。
- 文字覆盖在图片上时可读性更好。
尤其是本地素材来源不完全一致时,这种“主题色 + 半透明图片 + 渐变”的组合能快速提升整体一致性。
渐变层保证文字可读
FeatureCard 里有渐变遮罩:
Column()
.width('100%')
.height(150)
.linearGradient({
angle: 180,
colors: [['#00000011', 0.0], ['#000000CC', 1.0]]
})
很多图片上半部分亮、下半部分暗,或者主体颜色复杂。如果直接放文字,白字可能在雪山、湖面、天空上消失。
渐变层的作用不是装饰,而是可读性保障。
详情页头图可以更“沉浸”
详情页头图组件接收颜色和图片:
@Builder
DetailHero(color: string, image: Resource) {
Stack() {
Column()
.width('100%')
.height(244)
.backgroundColor(color)
Image(image)
.width('100%')
.height(244)
.objectFit(ImageFit.Cover)
.opacity(0.82)
}
.height(244)
}
头图比列表图更高,因为详情页的目的不是快速扫读,而是让用户进入一个目的地内容。
旅行类详情页可以大胆使用更高的头图,但要注意两个问题:
- 内容面板要向上衔接,避免上下割裂。
- 顶部返回按钮要保证在图片上可见。
图片命名要有规则
项目里的图片基本遵循:
img_地点或内容.jpg
例如:
img_kanas.jpg
img_sayram.jpg
img_kashgar_oldtown.jpg
img_dapanji.jpg
img_laghman.jpg
命名规则看似小事,但资源一多就很重要。建议遵守:
- 全小写。
- 单词用下划线。
- 景点用英文或拼音稳定命名。
- 不用
1.jpg、new.jpg、test.jpg。 - 启动页、图标单独命名。
后续维护内容库时,资源名能直接对应数据 id,效率会高很多。
离线图片的包体权衡
离线 App 的图片都随包发布,因此要关注包体积。
这个项目的素材单张图片大多在几十 KB 到几百 KB 之间,适合 MVP。后续如果内容扩展到数百张图片,需要考虑:
- 压缩 JPG 质量。
- 控制图片尺寸,不要直接放超大原图。
- 区分缩略图和详情图。
- 对路线、城市复用同一张封面。
- 后续版本考虑可选离线包下载。
图片越多,越要避免“每个页面都上一张 2MB 原图”的做法。
| 场景 | 推荐资源策略 | 原因 |
|---|---|---|
| 首页卡片 | 中等尺寸 JPG | 列表多图,优先控制加载压力 |
| 详情头图 | 较高清封面 | 用户停留时间长,视觉收益高 |
| 启动页 | 单张压缩图 | 避免冷启动阶段等待过久 |
| 商店截图 | 单独导出 PNG/JPEG | 不和应用运行资源混在一起 |
离线 App 的图片策略要同时考虑视觉和包体。素材不是越大越好,而是要匹配显示位置。
验证清单
| 检查项 | 操作方式 | 通过标准 |
|---|---|---|
| 所有 Markdown 配图都是本地 PNG | 对照项目文件或真机/模拟器操作 | 结果符合文章描述 |
| App 图片资源都能通过 $r 引用 | 对照项目文件或真机/模拟器操作 | 结果符合文章描述 |
| 启动背景色和启动页主色一致 | 对照项目文件或真机/模拟器操作 | 结果符合文章描述 |
| 卡片图片使用固定容器和 Cover | 对照项目文件或真机/模拟器操作 | 结果符合文章描述 |
| 图片上文字有遮罩保证可读 | 对照项目文件或真机/模拟器操作 | 结果符合文章描述 |
常见问题和处理
| 问题现象 | 优先排查 | 处理方式 |
|---|---|---|
| 启动瞬间白屏明显 | 检查 startWindowBackground | 应用内启动页背景色要一致 |
| 图片被拉伸 | 检查是否使用 Cover | 不要只给宽度不给高度 |
| 包体积增长快 | 检查图片尺寸和质量 | 缩略图与详情图可分层管理 |
本篇小结
资源与图片体验的关键点:
- 图片资源通过
$r('app.media.xxx')引用。 - 数据模型直接保存
Resource。 - 系统启动窗口和应用内启动页保持色彩一致。
- 图片展示统一使用
ImageFit.Cover。 - 主题色和渐变层用于提高视觉一致性和文字可读性。
- 图片命名要规则化,为后续扩展做准备。
下一篇我们看适配和质量:如何处理长文案、空状态、固定栏遮挡、平板设备和可发布前的视觉稳定性。
更多推荐


所有评论(0)