页面预览

图片编辑器界面设计图

前言

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

图片编辑器 让用户选择图片后添加文字、滤镜等效果。小分享 App 的 ImageEditPage 采用黑色主题背景,使用 position 属性实现文字叠加在图片上。本篇讲解 黑色主题设计position 绝对定位滤镜条横向滚动@State 选中态管理 等核心实现。详细 API 可参考 HarmonyOS position 官方文档

一、ImageEditPage 完整代码

1.1 页面完整实现

import router from '@ohos.router';
import { FilterItem } from '../common/interfaces';

@Entry
@Component
struct ImageEditPage {
  @State selectedFilter: number = 0;

  private filters: Array<FilterItem> = [
    { name: '原图', color: '#F0F0F0' },
    { name: '清新', color: '#E8F5E9' },
    { name: '暖色', color: '#FFF3E0' },
    { name: '胶片', color: '#F3E5F5' },
    { name: '黑白', color: '#E0E0E0' },
    { name: '复古', color: '#EFEBE9' }
  ];

  build() {
    Column() {
      // Header
      this.HeaderBar()
      // 图片预览区 + 文字叠加
      this.ImagePreview()
      // 底部工具栏
      this.BottomToolbar()
    }
    .width('100%').height('100%').backgroundColor('#1A1A1A')
  }
}

二、黑色主题设计

2.1 黑色背景

.width('100%').height('100%').backgroundColor('#1A1A1A')

黑色主题的页面结构:

Column (主容器,黑色背景 #1A1A1A)
├─ Row (Header,白色背景)
├─ Column (图片预览区,黑色背景)
│   ├─ Column (图片占位,灰色 #F0F0F0)
│   └─ Column (文字叠加层,position 定位)
└─ Column (工具栏,白色背景)

2.2 Header 导航栏

Row() {
  Text('‹').fontSize(24).fontColor('#1A1A1A')
    .onClick(() => { router.back() })
  Text('图片编辑').fontSize(18).fontWeight(FontWeight.Bold)
    .fontColor('#1A1A1A').layoutWeight(1).textAlign(TextAlign.Center)
  Text('完成').fontSize(16).fontColor('#F5A623')
    .onClick(() => { router.pushUrl({ url: 'pages/SharePreviewPage' }) })
}
.width('100%').padding({ left: 16, right: 16, top: 12, bottom: 12 })
.backgroundColor(Color.White)

三、position 文字叠加

3.1 position 定位

Column({ space: 8 }) {
  Text('山川湖海,').fontSize(24).fontWeight(FontWeight.Bold).fontColor(Color.White)
  Text('天地与爱。').fontSize(24).fontWeight(FontWeight.Bold).fontColor(Color.White)
}
.position({ x: 24, y: 200 })

3.2 position 参数

参数 说明
x 24 距左侧 24vp
y 200 距顶部 200vp

3.3 position 各模式

模式 语法 说明
绝对定位 position({x, y}) 相对于父容器定位
相对定位 offset({x, y}) 相对于自身原始位置
百分比 position('50%', '50%') 相对于父容器百分比

提示:position 定位的元素会脱离文档流,不会影响其他元素的布局。

四、滤镜条横向滚动

4.1 横向 Scroll

Scroll() {
  Row({ space: 12 }) {
    ForEach(this.filters, (item: FilterItem, index: number) => {
      Column({ space: 6 }) {
        Column().width(56).height(56)
          .backgroundColor(item.color).borderRadius(8)
          .border({ width: this.selectedFilter === index ? 2 : 0, color: '#F5A623' })
          .onClick(() => { this.selectedFilter = index })

        Text(item.name).fontSize(11)
          .fontColor(this.selectedFilter === index ? '#F5A623' : '#666666')
      }
      .alignItems(HorizontalAlign.Center)
    }, (item: FilterItem, index: number) => item.name)
  }
  .padding({ left: 16, right: 16 })
}
.scrollable(ScrollDirection.Horizontal).scrollBar(BarState.Off)

4.2 滤镜列表

滤镜 索引 色值 说明
原图 0 #F0F0F0 无效果
清新 1 #E8F5E9 绿色调
暖色 2 #FFF3E0 暖色调
胶片 3 #F3E5F5 紫色调
黑白 4 #E0E0E0 灰度
复古 5 #EFEBE9 棕色系

五、@State 选中态管理

5.1 选中态逻辑

@State selectedFilter: number = 0

5.2 选中态视觉反馈

// 边框 - 选中时显示 2px 橙色边框
.border({
  width: this.selectedFilter === index ? 2 : 0,
  color: '#F5A623'
})

// 文字颜色 - 选中时变为主色
.fontColor(this.selectedFilter === index ? '#F5A623' : '#666666')

六、工具栏按钮

6.1 @Builder 封装

@Builder ToolBtn(icon: string, label: string) {
  Column({ space: 4 }) {
    Text(icon).fontSize(20)
    Text(label).fontSize(11).fontColor('#666666')
  }
  .alignItems(HorizontalAlign.Center)
}

6.2 工具栏布局

Row({ space: 0 }) {
  this.ToolBtn('', '滤镜')
  this.ToolBtn('', '调整')
  this.ToolBtn('', '贴纸')
  this.ToolBtn('T', '文字')
  this.ToolBtn('', '裁剪')
}
.width('100%').height(60).backgroundColor(Color.White)
.justifyContent(FlexAlign.SpaceAround)

七、路由跳转

7.1 完成按钮

Text('完成').fontSize(16).fontColor('#F5A623')
  .onClick(() => { router.pushUrl({ url: 'pages/SharePreviewPage' }) })

7.2 返回按钮

Text('‹').fontSize(24).fontColor('#1A1A1A')
  .onClick(() => { router.back() })

八、常见问题

8.1 问题 1:position 定位不生效

原因:父容器没有设置 widthheight

解决:确保父容器有明确的宽高值。

8.2 问题 2:横向 Scroll 不滚动

原因:Row 没有足够的宽度(Row 的宽度应该由内容撑开)。

解决:不要给 Row 设置 width('100%'),让内容决定宽度。

九、核心知识点

9.1 技术要点

  • 黑色背景用 backgroundColor('#1A1A1A')
  • 文字叠加用 position({x, y}) 绝对定位
  • 滤镜条横向滚动用 Scroll(scrollable: Horizontal)
  • 选中态用 @State + border 条件渲染

9.2 实战建议

  • 黑色背景提升编辑视觉沉浸感
  • position 定位文字在图片上
  • 滤镜选中态用 border 条件渲染

总结

本文详细讲解了 ImageEditPage 图片编辑器的完整实现,从 黑色主题设计position 文字叠加滤镜条横向滚动@State 选中态管理,涵盖了图片编辑器的全部核心功能。下一篇我们将深入 LinkEditPage 链接分享的实现。

附录:图片编辑器的完整实现细节

1. 完整的页面结构

Column (主容器,黑色背景 #1A1A1A)
├─ Row (Header 导航栏,白色背景)
│   ├─ Text('‹') 返回按钮
│   ├─ Text('图片编辑') 标题
│   └─ Text('完成') 跳转按钮
├─ Column (图片预览区,黑色背景) - layoutWeight(1)
│   ├─ Column (图片占位,灰色 #F0F0F0)
│   │   └─ Text('') 80px Emoji
│   └─ Column (文字叠加层)
│       └─ position({x:24, y:200}) 定位
└─ Column (底部工具栏,白色背景)
    ├─ Row (工具行) - 滤镜/调整/贴纸/文字/裁剪
    └─ Scroll (滤镜条,横向滚动)
        └─ Row - 6 个滤镜缩略图

2. 工具栏按钮详解

@Builder ToolBtn(icon: string, label: string) {
  Column({ space: 4 }) {
    Text(icon).fontSize(20)
    Text(label).fontSize(11).fontColor('#666666')
  }
  .alignItems(HorizontalAlign.Center)
}

3. 滤镜选中态的实现方式

状态 边框宽度 边框颜色 文字颜色
选中 2px #F5A623 #F5A623
未选中 0px 透明 #666666

4. 与文字编辑器的对比

对比维度 ImageEditPage TextEditPage
背景色 黑色 #1A1A1A 白色 #FFFFFF
文字叠加 position 定位 直接排列
滤镜 6 种滤镜预设
工具栏 双行(工具+滤镜) 双行(工具+格式)
跳转目标 SharePreviewPage PreviewPage

5. 扩展方向

  1. 真实图片选择:集成 PhotoViewPicker
  2. 真实滤镜处理:集成 EffectKit
  3. 图片裁剪功能:集成 ImageEditor
  4. 贴纸功能:预置贴纸库
  5. 文字样式:字号、颜色、字体选择

以上扩展功能将在后续文章详细介绍。

6. 滤镜数据模型

export interface FilterItem {
  name: string;   // 滤镜名称
  color: string;  // 滤镜预览色值
}

private filters: Array<FilterItem> = [
  { name: '原图', color: '#F0F0F0' },
  { name: '清新', color: '#E8F5E9' },
  { name: '暖色', color: '#FFF3E0' },
  { name: '胶片', color: '#F3E5F5' },
  { name: '黑白', color: '#E0E0E0' },
  { name: '复古', color: '#EFEBE9' }
];

7. 键盘快捷键支持

// 返回键处理
.onClick(() => { router.back() })

// 完成键处理
.onClick(() => { router.pushUrl({ url: 'pages/SharePreviewPage' }) })

8. 性能优化建议

优化项 建议 原因
滤镜预览 使用缩略图而非全尺寸 减少内存占用
图片加载 异步加载 避免阻塞 UI
工具栏 使用 @Builder 复用 减少重复代码
状态管理 最小化 @State 使用 减少不必要的 UI 刷新

9. 完整代码索引

文件路径 说明
pages/ImageEditPage.ets 图片编辑器页面
common/interfaces.ets FilterItem 接口定义
components/BottomTabBar.ets 底部导航栏组件

10. 本文涉及的所有 API

API 用途 文档链接
@State 状态管理 State Guide
@Builder UI 复用 Builder Guide
position() 绝对定位 Position
Scroll 横向滚动 Scroll Component
border() 边框样式 Border
router.pushUrl() 路由跳转 Router
router.back() 返回 Router

以上 API 的详细用法可参考 HarmonyOS 官方文档。

11. 实现要点总结

图片编辑器的核心实现要点:

  1. 黑色主题:使用 #1A1A1A 深色背景营造沉浸式编辑体验
  2. 文字叠加:通过 position({x, y}) 将文字层定位在图片之上
  3. 滤镜横向滚动Scroll + ScrollDirection.Horizontal 实现横向滑动
  4. 选中态反馈border 条件渲染 + fontColor 条件渲染
  5. @Builder 复用:工具栏按钮通过 @Builder 封装

下一步优化方向:

  • 集成 PhotoViewPicker 实现真实图片选择
  • 集成 EffectKit 实现真实滤镜效果
  • 集成 ImageEditor 实现裁剪和旋转功能

12. 本文总结

本文详细讲解了 ImageEditPage 图片编辑器的完整实现。核心知识点包括:黑色主题设计#1A1A1A 背景营造沉浸式编辑体验)、position 文字定位(在图片上叠加文字层)、滤镜横向滚动Scroll + ScrollDirection.Horizontal 实现横向滑动)、@State 选中态管理border 条件渲染 + fontColor 条件渲染)。这些技术构成了图片编辑器的完整实现基础,后续可扩展真实图片选择和滤镜处理。在下一篇文章中,我们将继续探讨 LinkEditPage 链接分享编辑器的实现。

  • LinkEditPage 链接分享——PreviewCard + Toggle 开关

如果这篇文章对你有帮助,欢迎点赞👍、收藏⭐、关注🔔,你的支持是我持续创作的动力!

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐