27.[HarmonyOS NEXT Column案例六(下)] 任务项交互设计:条件渲染与事件处理的高级应用

2025-05-31 23:57:23
429次阅读
0个评论

项目已开源,开源地址: https://gitcode.com/nutpi/HarmonyosNextCaseStudyTutorial , 欢迎fork & star

效果演示

img_d1db99be.png

1. 引言

在上一部分中,我们介绍了任务列表的基础结构、数据模型设计以及外层Column的实现。本教程将继续深入探讨TaskItem组件的内部结构,包括Row布局的实现、条件渲染的使用以及交互事件的处理,帮助开发者掌握更复杂的布局和交互技巧,创建功能丰富、用户体验良好的任务列表界面。

2. TaskItem组件设计

2.1 组件定义与状态管理

@Component
struct TaskItem {
    @Prop task: string
    @State showActions: boolean = false

    build() {
        // 组件内容
    }
}
装饰器 属性 类型 初始值 说明
@Component - - - 标识这是一个自定义组件
@Prop task string - 从父组件接收的任务文本,只读属性
@State showActions boolean false 组件内部状态,控制操作按钮的显示与隐藏

2.2 装饰器的作用与区别

2.2.1 @Component装饰器

@Component装饰器用于定义自定义组件,它告诉框架这是一个可复用的UI组件,具有自己的生命周期和渲染逻辑。

2.2.2 @Prop装饰器

@Prop装饰器用于定义从父组件接收的属性,特点包括:

  1. 单向数据流:父组件可以修改属性值,子组件只能读取不能修改
  2. 响应式:当父组件中的值变化时,子组件会自动更新
  3. 简单传递:适用于传递简单数据类型或只读对象

2.2.3 @State装饰器

@State装饰器用于定义组件的内部状态,特点包括:

  1. 组件私有:状态只在组件内部可见和修改
  2. 响应式:状态变化会触发组件重新渲染
  3. 状态持久:在组件生命周期内保持状态

在TaskItem组件中,我们使用@State装饰器定义了showActions状态,用于控制操作按钮的显示与隐藏,初始值为false(隐藏状态)。

3. Row布局实现

3.1 基本结构

Row({ space: 16 })
{
    // 任务内容(垂直排列)
    Column({ space: 4 }) {
        // 文本组件
    }

    // 操作按钮(水平排列,悬停显示)
    if (this.showActions) {
        Row({ space: 8 }) {
            // 按钮组件
        }
        .alignItems(VerticalAlign.Center)
        .justifyContent(FlexAlign.Center)
    }
}
.width('100%')
.padding({ left: 12,right:12, top: 16, bottom: 16 })
.backgroundColor(0xFFFFFF)
.borderRadius(8)
.shadow({ radius: 2, color: 0x05000000 })
.onHover((isHover: boolean, event: HoverEvent)=>{
    // 悬停事件处理
})

每个任务项使用Row组件实现水平布局,将任务内容和操作按钮分别放置在左右两侧。

3.2 Row属性详解

属性/参数 值 作用
space 16 设置子组件之间的水平间距为16vp
width 100% 设置Row宽度占父容器的100%
padding { left: 12,right:12, top: 16, bottom: 16 } 设置内边距,上下16vp,左右12vp
backgroundColor 0xFFFFFF 设置背景色为白色
borderRadius 8 设置边框圆角为8vp
shadow { radius: 2, color: 0x05000000 } 设置阴影效果,营造卡片视觉

3.3 卡片式设计的实现

.backgroundColor(0xFFFFFF)
.borderRadius(8)
.shadow({ radius: 2, color: 0x05000000 })

这三个属性的组合实现了卡片式设计:

  1. 白色背景提供了与页面背景的对比
  2. 圆角边框柔化了卡片的视觉边界
  3. 轻微的阴影效果增强了层次感,使卡片看起来略微悬浮

阴影参数解析:

参数 值 说明
radius 2 阴影扩散半径,值越大阴影越模糊
color 0x05000000 阴影颜色,0x05表示透明度为5%的黑色阴影

4. 任务内容区域的Column布局

4.1 基本结构

Column({ space: 4 }) {
    Text(this.task)
        .fontSize(16)
        .fontWeight(500)
    Text('2025-05-30 14:00')
        .fontSize(12)
        .fontColor(0x666666)
}

任务内容区域使用Column组件垂直排列任务标题和日期信息。

4.2 Column属性详解

属性/参数 值 作用
space 4 设置子组件之间的垂直间距为4vp

4.3 文本组件的实现

4.3.1 任务标题

Text(this.task)
    .fontSize(16)
    .fontWeight(500)
属性 值 作用
构造参数 this.task 设置文本内容,来自@Prop装饰的task属性
fontSize 16 设置字体大小为16vp
fontWeight 500 设置字体粗细为中等偏粗

4.3.2 任务日期

Text('2025-05-30 14:00')
    .fontSize(12)
    .fontColor(0x666666)
属性 值 作用
构造参数 '2025-05-30 14:00' 设置文本内容为固定的日期时间文本
fontSize 12 设置字体大小为12vp,小于标题字号
fontColor 0x666666 设置字体颜色为深灰色,弱化视觉重要性

4.4 文本层次设计

任务内容区域的文本设计遵循了明确的视觉层次:

  1. 主要信息(任务标题):较大字号(16vp)、较粗字重(500)、默认黑色
  2. 次要信息(任务日期):较小字号(12vp)、默认字重、灰色(0x666666)

这种设计使用户能够快速识别重要信息,同时在需要时也能获取次要信息,提高了界面的可读性和信息层次感。

5. 操作按钮区域的条件渲染

5.1 条件渲染的实现

if (this.showActions) {
    Row({ space: 8 }) {
        Button('编辑')
            .width(48)
            .height(28)
            .fontSize(12)
            .backgroundColor(0xE0F5FF)
            .fontColor(0x007DFF)

        Button('删除')
            .width(48)
            .height(28)
            .fontSize(12)
            .backgroundColor(0xFFF0F0)
            .fontColor(0xFF4D4F53)
    }
    .alignItems(VerticalAlign.Center)
    .justifyContent(FlexAlign.Center)
}

条件渲染使用if语句实现,只有当showActions为true时,才会渲染操作按钮区域。

5.2 Row布局属性

属性/参数 值 作用
space 8 设置按钮之间的水平间距为8vp
alignItems VerticalAlign.Center 设置子组件在垂直方向上居中对齐
justifyContent FlexAlign.Center 设置子组件在水平方向上居中对齐

5.3 按钮样式设计

5.3.1 编辑按钮

Button('编辑')
    .width(48)
    .height(28)
    .fontSize(12)
    .backgroundColor(0xE0F5FF)
    .fontColor(0x007DFF)
属性 值 作用
构造参数 '编辑' 设置按钮文本
width 48 设置按钮宽度为48vp
height 28 设置按钮高度为28vp
fontSize 12 设置字体大小为12vp
backgroundColor 0xE0F5FF 设置背景色为浅蓝色
fontColor 0x007DFF 设置文字颜色为蓝色

5.3.2 删除按钮

Button('删除')
    .width(48)
    .height(28)
    .fontSize(12)
    .backgroundColor(0xFFF0F0)
    .fontColor(0xFF4D4F53)
属性 值 作用
构造参数 '删除' 设置按钮文本
width 48 设置按钮宽度为48vp
height 28 设置按钮高度为28vp
fontSize 12 设置字体大小为12vp
backgroundColor 0xFFF0F0 设置背景色为浅红色
fontColor 0xFF4D4F53 设置文字颜色为红色

5.4 按钮的视觉差异化

两个按钮使用了不同的颜色方案来区分不同的操作类型:

  1. 编辑按钮:蓝色系(浅蓝背景 + 蓝色文字),表示中性操作
  2. 删除按钮:红色系(浅红背景 + 红色文字),表示危险操作

这种颜色编码符合用户的心理预期,使界面更加直观易用。

6. 交互事件处理

6.1 悬停事件的实现

.onHover((isHover: boolean, event: HoverEvent)=>{
    if (isHover) {this.showActions = true}else{
        this.showActions = false
    }
})

onHover事件用于检测鼠标是否悬停在组件上,它接收一个回调函数,该函数有两个参数:

参数 类型 说明
isHover boolean 表示鼠标是否悬停在组件上
event HoverEvent 包含事件详细信息的对象

6.2 状态管理与UI更新

if (isHover) {this.showActions = true}else{
    this.showActions = false
}

这段代码根据悬停状态更新showActions状态变量:

  1. 当鼠标悬停在任务项上时(isHover为true),将showActions设为true,显示操作按钮
  2. 当鼠标离开任务项时(isHover为false),将showActions设为false,隐藏操作按钮

由于showActions是使用@State装饰器定义的响应式状态变量,当其值变化时,框架会自动重新渲染组件,实现操作按钮的动态显示与隐藏。

6.3 交互设计的优势

这种基于悬停的交互设计有以下优势:

  1. 界面简洁:默认情况下不显示操作按钮,减少视觉干扰
  2. 按需显示:只有当用户需要操作时(鼠标悬停),才显示相关按钮
  3. 直观反馈:提供即时的视觉反馈,增强用户体验
  4. 空间节省:在不牺牲功能的情况下,节省界面空间

7. 完整代码分析

让我们回顾完整的TaskItem组件代码:

@Component
struct TaskItem {
    @Prop task: string
    @State showActions: boolean = false

    build() {
        Row({ space: 16 })
        {

            // 任务内容(垂直排列)
            Column({ space: 4 }) {
                Text(this.task)
                    .fontSize(16)
                    .fontWeight(500)
                Text('2025-05-30 14:00')
                    .fontSize(12)
                    .fontColor(0x666666)
            }

            // 操作按钮(水平排列,悬停显示)
            if (this.showActions) {
                Row({ space: 8 }) {
                    Button('编辑')
                        .width(48)
                        .height(28)
                        .fontSize(12)
                        .backgroundColor(0xE0F5FF)
                        .fontColor(0x007DFF)

                    Button('删除')
                        .width(48)
                        .height(28)
                        .fontSize(12)
                        .backgroundColor(0xFFF0F0)
                        .fontColor(0xFF4D4F53)
                }
                .alignItems(VerticalAlign.Center)
                .justifyContent(FlexAlign.Center)
            }
        }
        .width('100%')
        .padding({ left: 12,right:12, top: 16, bottom: 16 })
        .backgroundColor(0xFFFFFF)
        .borderRadius(8)
        .shadow({ radius: 2, color: 0x05000000 })
        .onHover((isHover: boolean, event: HoverEvent)=>{
            if (isHover) {this.showActions = true}else{
                this.showActions = false
            }
        }) // 鼠标悬停显示操作按钮

    }
}

7.1 代码结构分析

  1. 组件定义:使用@Component装饰器定义TaskItem自定义组件
  2. 属性与状态:定义@Prop属性接收任务文本,定义@State状态控制操作按钮显示
  3. 布局结构:
    • 外层Row:水平排列任务内容和操作按钮
    • 内层Column:垂直排列任务标题和日期
    • 条件渲染Row:根据状态显示或隐藏操作按钮
  4. 样式设置:设置卡片式样式,包括背景色、圆角和阴影
  5. 交互处理:通过onHover事件实现鼠标悬停交互

7.2 布局嵌套层次

本案例展示了多层嵌套布局的实现方式:

  1. 第一层:TaskItem组件的Row(水平排列)
  2. 第二层:左侧Column(垂直排列)和右侧条件渲染Row(水平排列)
  3. 第三层:文本组件和按钮组件

这种多层嵌套的布局结构能够实现复杂的界面设计,同时保持代码的清晰和可维护性。

8. 总结

通过本教程的两个部分,我们详细讲解了如何使用Column和Row组件的嵌套组合,结合自定义组件和条件渲染,创建一个交互式任务列表

收藏0赞0

请 登录 后评论。没有帐号? 注册 一个。

全栈若城

  • 0回答
  • 5粉丝
  • 0关注