HarmonyOS应用开发实战:萌宠日记 - 照片附件区与添加按钮布局
前言
照片附件是日记编辑中重要的功能模块,用户可以在记录文字的同时添加照片,让日记更加生动。在萌宠日记的日记编辑器中,照片附件区使用水平 Row 布局展示已选照片和添加按钮,每张照片以80×80vp 的方形占位图呈现,添加按钮使用+符号区分于照片。
本文将从萌宠日记的照片附件区实现出发,深入解析照片占位图设计、添加按钮样式、水平滚动布局、以及图片选择与预览的扩展方案。
一、照片附件区整体设计
1.1 布局结构
┌─────────────────────────────────────┐ │ ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐│ │ │ 🐶 │ │ 🐶 │ │ 🐶 │ │ + ││ │ │ │ │ │ │ │ │ ││ │ └──────┘ └──────┘ └──────┘ └──────┘│ └─────────────────────────────────────┘1.2 完整代码
// WriteDiaryPage.ets — 照片附件区 Row({ space: 8 }) { // 已有照片 ForEach([0, 1, 2], (_: number) => { Column() { Text('🐶') .fontSize(32) } .width(80) .height(80) .backgroundColor('#FFF3E0') .borderRadius(12) .justifyContent(FlexAlign.Center) }) // 添加照片按钮 Column() { Text('+') .fontSize(28) .fontColor('#CCCCCC') } .width(80) .height(80) .backgroundColor('#F5F5F5') .borderRadius(12) .justifyContent(FlexAlign.Center) } .width('100%')提示:照片附件区使用Row 水平布局,每个照片项和添加按钮使用相同的80×80vp 尺寸,视觉上统一、整齐。添加按钮使用
backgroundColor('#F5F5F5')灰色背景和+符号,与照片的#FFF3E0浅橙背景形成区分。
二、照片占位图设计
2.1 占位图样式
// 照片占位图 Column() { Text('🐶') // Emoji 占位 .fontSize(32) } .width(80) // 固定宽高 .height(80) .backgroundColor('#FFF3E0') // 浅橙背景 .borderRadius(12) // 圆角 .justifyContent(FlexAlign.Center) // 内容居中2.2 占位图参数
| 参数 | 值 | 说明 |
|---|---|---|
| 尺寸 | 80×80vp | 标准缩略图大小 |
| 背景色 | #FFF3E0 | 浅橙,与主色调呼应 |
| 圆角 | 12vp | 圆角矩形 |
| Emoji 大小 | 32fp | 大号 Emoji 清晰可辨 |
| 内容居中 | FlexAlign.Center | 垂直居中 |
三、添加按钮设计
3.1 添加按钮样式
// 添加照片按钮 Column() { Text('+') .fontSize(28) .fontColor('#CCCCCC') // 浅灰色加号 } .width(80) .height(80) .backgroundColor('#F5F5F5') // 浅灰背景(与照片背景区分) .borderRadius(12) .justifyContent(FlexAlign.Center) .onClick(() => { // 打开相册选择图片 this.selectPhotos() })3.2 照片与添加按钮的对比
| 对比维度 | 已有照片 | 添加按钮 |
|---|---|---|
| 背景色 | #FFF3E0浅橙 | #F5F5F5浅灰 |
| 内容 | Emoji 图片 | +符号 |
| 字号 | 32fp | 28fp |
| 交互 | 点击查看大图 | 点击添加照片 |
| 语义 | 已选照片 | 添加新照片 |
四、水平滚动扩展
4.1 可滚动照片列表
// 照片较多时使用 Scroll 水平滚动 Scroll() { Row({ space: 8 }) { ForEach(this.photos, (photo: PhotoInfo) => { // 照片项 }) // 添加按钮 Column() { Text('+').fontSize(28).fontColor('#CCCCCC') } .width(80).height(80) .backgroundColor('#F5F5F5') .borderRadius(12) .justifyContent(FlexAlign.Center) .onClick(() => this.selectPhotos()) } } .scrollable(ScrollDirection.Horizontal) // 水平滚动 .scrollBar(BarState.Off) // 隐藏滚动条五、图片选择流程
5.1 选择图片
// 使用 PhotoPicker 选择图片 import { photoAccessHelper } from '@kit.MediaLibraryKit' async selectPhotos(): Promise<void> { try { const picker = new photoAccessHelper.PhotoPicker() const result = await picker.select({ MIME_TYPE: ['image/*'], maxSelectCount: 9 // 最多选择 9 张 }) if (result.photoUris.length > 0) { this.addPhotos(result.photoUris) } } catch (err) { console.error('Photo picker failed:', JSON.stringify(err)) } }5.2 添加照片到列表
@State photos: string[] = [] // 照片 URI 列表 addPhotos(uris: string[]): void { this.photos = [...this.photos, ...uris] }六、照片删除功能
6.1 删除按钮
// 每张照片添加删除按钮 Column() { Stack() { // 照片 Image(photoUri) .width(80).height(80).borderRadius(12) // 删除按钮(右上角) Text('✕') .fontSize(14) .fontColor(Color.White) .backgroundColor('#80000000') .width(20).height(20) .borderRadius(10) .position({ x: 60, y: -5 }) .onClick(() => this.removePhoto(photoUri)) } .width(80).height(80) }6.2 删除逻辑
removePhoto(uri: string): void { const index = this.photos.indexOf(uri) if (index !== -1) { this.photos.splice(index, 1) } }七、照片预览功能
7.1 点击查看大图
// 点击照片查看大图 Column() { Image(photoUri) .width(80).height(80).borderRadius(12) } .onClick(() => { // 跳转到图片预览页 this.diaryStack.pushPath({ name: 'photoPreview', param: { photos: this.photos, index: index } }) })八、照片数量限制
8.1 限制逻辑
const MAX_PHOTOS = 9 // 最多 9 张 // 是否显示添加按钮 if (this.photos.length < MAX_PHOTOS) { // 显示添加按钮 } // 添加时检查数量 async selectPhotos(): Promise<void> { const remaining = MAX_PHOTOS - this.photos.length if (remaining <= 0) return // 最多选择 remaining 张 }九、无障碍适配
// 照片的无障碍描述 Column() { Image(photoUri).width(80).height(80) } .accessibilityText('日记照片') // 添加按钮的无障碍描述 Column() { Text('+').fontSize(28) } .accessibilityText('添加照片')十、最佳实践
10.1 照片附件区设计原则
有序列表 — 照片附件区设计的 5 个原则:
- 统一尺寸:所有照片和添加按钮使用相同尺寸,视觉整齐
- 视觉区分:添加按钮使用不同背景色和
+符号,与照片区分 - 水平滚动:照片较多时使用水平滚动,不占用垂直空间
- 数量限制:合理限制照片数量(建议 9 张),避免性能问题
- 删除方便:每张照片提供删除按钮,方便用户调整
10.2 萌宠日记照片附件区总结
| 设计要素 | 值 | 说明 |
|---|---|---|
| 照片尺寸 | 80×80vp | 标准缩略图 |
| 照片背景 | #FFF3E0浅橙 | 温暖色调 |
| 添加按钮背景 | #F5F5F5浅灰 | 与照片区分 |
| 圆角 | 12vp | 圆角矩形 |
| 间距 | 8vp | Row space |
| 最大数量 | 9 张 | 合理限制 |
总结
本文从萌宠日记的照片附件区实现出发,深入解析了照片选择与展示的完整方法:
- 布局设计:Row 水平排列,80×80vp 统一尺寸
- 占位图设计:Emoji 占位 + 浅橙背景
- 添加按钮:
+符号 + 浅灰背景,视觉区分 - 水平滚动:Scroll + 水平滚动,支持多张照片
- 图片选择:PhotoPicker 选择图片
- 删除功能:每张照片的删除按钮
- 预览功能:点击查看大图
- 数量限制:最多 9 张照片
照片附件区是日记编辑器中重要的功能模块,合理的布局和交互设计能显著提升用户的记录体验。
下一篇我们将深入地点与天气标签选择器,解析日记编辑器中的标签选择功能。
如果这篇文章对你有帮助,欢迎点赞👍、收藏⭐、关注🔔,你的支持是我持续创作的动力!
相关资源:
- Image 组件:https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-basic-components-image
- Scroll 组件:https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-container-scroll
- PhotoPicker:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/photo-picker
- Row 组件:https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-container-row
- Stack 组件:https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-container-stack
- 图片缓存优化:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/image-optimization
- 无障碍开发:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/accessibility-kit
- 媒体库开发:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/media-library