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

案例演示

1. 引言

在上一篇教程中,我们介绍了Column组件的reverse属性及其在时间线应用中的基本用法。本篇将深入探讨时间线中各个子组件的实现细节,包括ForEach循环渲染、Row布局、Text组件的样式设置,以及如何通过这些组件构建一个完整的时间线界面。

2. ForEach循环渲染消息列表

在时间线应用中,需要渲染多条消息,这时可以使用ForEach进行循环渲染。

2.1 ForEach的基本用法

在我们的案例中,ForEach的使用如下:

ForEach(this.messages.reverse(), (msg:string, index) => {
    // 渲染每条消息
}, (msg:string) => msg)

2.2 ForEach参数详解

ForEach接受三个参数:

参数类型描述
第一个参数数组要遍历的数据源,这里是反转后的消息数组
第二个参数回调函数定义如何渲染每个数组元素,接收当前元素和索引作为参数
第三个参数回调函数为每个元素生成唯一标识符,用于优化渲染性能

2.3 唯一标识符的重要性

ForEach的第三个参数用于生成唯一标识符,这对于列表渲染的性能优化非常重要:

(msg:string) => msg

在本例中,直接使用消息字符串作为唯一标识符。在实际应用中,如果数据是对象数组,通常会使用对象的唯一ID属性作为标识符。

3. Row布局实现消息项

每条消息项使用Row组件实现水平布局,包含时间戳和消息内容两部分。

3.1 Row组件的基本结构

Row({ space: 8 })
{
    // 时间戳
    Text(msg.split(': ')[0])
        .fontSize(12)
        .fontColor(0x666666)
        .width(80)
        .textAlign(TextAlign.Start)
        .textOverflow({ overflow:TextOverflow.MARQUEE })

    // 消息内容
    Text(msg.split(': ')[1])
        .fontSize(14)
        .lineHeight(1.5)
        .flexGrow(1)
        .textOverflow({ overflow:TextOverflow.MARQUEE })
}
.width('100%')
.padding(12)
.backgroundColor(index % 2 === 0 ? 0xF5F5F5 : 0xFFFFFF) // 交替背景色
.borderRadius(8)

3.2 Row组件参数详解

参数/属性作用
space8设置子组件之间的水平间距为8vp
width'100%'设置Row宽度占父容器的100%
padding12设置内边距为12vp
backgroundColor条件表达式根据索引设置交替背景色
borderRadius8设置边框圆角为8vp

3.3 交替背景色的实现

交替背景色是列表显示的常用技巧,可以提高可读性。在我们的案例中,通过索引的奇偶性来设置不同的背景色:

.backgroundColor(index % 2 === 0 ? 0xF5F5F5 : 0xFFFFFF) // 交替背景色
  • 当索引为偶数时,背景色为浅灰色(0xF5F5F5)
  • 当索引为奇数时,背景色为白色(0xFFFFFF)

4. Text组件样式定制

时间线中的每条消息包含两个Text组件:时间戳和消息内容,它们有不同的样式设置。

4.1 时间戳Text组件

// 时间戳
Text(msg.split(': ')[0])
    .fontSize(12)
    .fontColor(0x666666)
    .width(80)
    .textAlign(TextAlign.Start)
    .textOverflow({ overflow:TextOverflow.MARQUEE })

4.1.1 时间戳Text组件属性详解

属性作用
fontSize12设置字体大小为12vp,较小的字体适合时间戳
fontColor0x666666设置字体颜色为深灰色,使其不太突兀
width80设置固定宽度为80vp,保证时间戳对齐
textAlignTextAlign.Start设置文本左对齐
textOverflow{ overflow:TextOverflow.MARQUEE }设置文本溢出时显示为跑马灯效果

4.2 消息内容Text组件

// 消息内容
Text(msg.split(': ')[1])
    .fontSize(14)
    .lineHeight(1.5)
    .flexGrow(1)
    .textOverflow({ overflow:TextOverflow.MARQUEE })

4.2.1 消息内容Text组件属性详解

属性作用
fontSize14设置字体大小为14vp,比时间戳大,突出主要内容
lineHeight1.5设置行高为字体大小的1.5倍,提高可读性
flexGrow1设置弹性增长系数为1,使其占据剩余空间
textOverflow{ overflow:TextOverflow.MARQUEE }设置文本溢出时显示为跑马灯效果

4.3 文本溢出处理

TextOverflow是处理文本溢出的重要属性,在我们的案例中,使用了MARQUEE(跑马灯)效果:

.textOverflow({ overflow:TextOverflow.MARQUEE })

TextOverflow枚举值包括:

枚举值描述
CLIP裁剪溢出的文本
ELLIPSIS用省略号表示溢出的文本
MARQUEE跑马灯效果,文本会滚动显示
NONE不处理溢出文本,可能导致文本超出容器边界

5. 布局技巧与样式一致性

在时间线设计中,保持布局合理和样式一致性是提升用户体验的关键。

5.1 间距规范

元素间距
消息项之间16vp(通过Column的space参数设置)
时间戳与消息内容之间8vp(通过Row的space参数设置)
消息项内边距12vp(通过Row的padding设置)
列表与屏幕边缘24vp(通过Column的padding设置)

5.2 字体规范

元素字体大小字体颜色
时间戳12vp深灰色(0x666666)
消息内容14vp默认颜色(黑色)

5.3 颜色规范

元素颜色十六进制值
偶数项背景浅灰色0xF5F5F5
奇数项背景白色0xFFFFFF
时间戳文字深灰色0x666666
消息内容文字黑色默认

5.4 圆角规范

消息项统一使用8vp的圆角,保持视觉一致性。

6. 完整代码分析

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

@Component
export struct TimelineExample {
    private messages: string[] = [
        '2025-05-30 15:45: 您好,欢迎使用HarmonyOS NEXT!',
        '2025-05-30 15:40: 系统已为您更新最新通知',
        '2025-05-30 15:35: 您的订单已发货'
    ]

    build() {
        Column({ space: 16 })
             { // 固定高度,模拟列表容器
            ForEach(this.messages.reverse(), (msg:string, index) => { // 反转数组保持渲染顺序
                Row({ space: 8 })
                {
                    // 时间戳
                    Text(msg.split(': ')[0])
                        .fontSize(12)
                        .fontColor(0x666666)
                        .width(80)
                        .textAlign(TextAlign.Start)
                        .textOverflow({ overflow:TextOverflow.MARQUEE })


                    // 消息内容
                    Text(msg.split(': ')[1])
                        .fontSize(14)
                        .lineHeight(1.5)
                        .flexGrow(1)
                        .textOverflow({ overflow:TextOverflow.MARQUEE })
                }

                .width('100%')
                .padding(12)
                .backgroundColor(index % 2 === 0 ? 0xF5F5F5 : 0xFFFFFF) // 交替背景色
                .borderRadius(8)
            }, (msg:string) => msg)
        }.width('100%')
        .padding({ top: 24, left: 24, right: 24 })
        .reverse(true) // 子组件反向排列(新消息在上)
        .height('80%')
    }
}

6.1 代码结构分析

  1. 组件定义:使用@Component装饰器定义TimelineExample自定义组件
  2. 数据定义:定义messages字符串数组存储消息数据
  3. 布局容器:使用Column组件创建垂直布局,并设置reverse为true
  4. 循环渲染:使用ForEach循环渲染消息列表,并反转数组
  5. 消息项布局:使用Row组件创建水平布局,包含时间戳和消息内容
  6. 样式设置:为每个组件设置适当的样式属性
  7. 交替背景:根据索引设置交替背景色

6.2 实现要点总结

  1. 反向排列的两种方式

    • Column的reverse属性:控制子组件的排列方向
    • 数组的reverse()方法:控制数据的顺序
  2. 灵活的布局嵌套

    • Column作为外层容器,垂直排列消息项
    • Row作为消息项容器,水平排列时间戳和内容
  3. 样式的统一与区分

    • 统一的间距、圆角规范
    • 区分的字体大小、颜色设置
  4. 交互体验的优化

    • 交替背景色提高可读性
    • 文本溢出处理确保信息完整显示

7. 总结

通过本教程的两个部分,我们详细讲解了如何使用Column组件的reverse属性构建反向排列的时间线,包括:

  1. Column组件的reverse属性及其应用
  2. 数据处理与反转技巧
  3. ForEach循环渲染消息列表
  4. Row布局实现消息项
  5. Text组件的样式定制
  6. 布局技巧与样式一致性

全栈若城
1 声望2 粉丝