[HarmonyOS NEXT 实战案例六:List系列] 垂直列表组件实战:打造高效联系人列表 基础篇

2025-06-30 22:12:07
103次阅读
0个评论

[HarmonyOS NEXT 实战案例六:List系列] 垂直列表组件实战:打造高效联系人列表 基础篇

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

效果演示

image.png

一、List组件基础介绍

在HarmonyOS NEXT应用开发中,List组件是一个非常重要的容器组件,用于呈现同类数据项的集合。它支持垂直和水平方向的滚动,能够高效地展示大量数据,是开发中最常用的组件之一。

1.1 List组件的特点

特点 说明
高效渲染 采用懒加载机制,只渲染可视区域内的元素
灵活布局 支持垂直和水平方向的布局
丰富样式 支持分割线、滚动效果等多种样式定制
事件处理 提供丰富的事件回调,如滚动、触摸等
性能优化 针对大数据量场景做了专门优化

1.2 ListItem组件介绍

在List组件中,每个列表项都由ListItem组件构成。ListItem是List的子组件,用于定义列表中的单个数据项的布局和行为。

特点 说明
自定义内容 可以包含任意子组件,实现复杂的列表项布局
交互事件 支持点击、长按等交互事件
样式定制 可以设置高度、宽度、边距等样式属性

二、垂直列表实战案例

在本案例中,我们将实现一个垂直方向的联系人列表,展示联系人的头像、姓名和电话号码。

2.1 数据模型定义

首先,我们需要定义联系人的数据模型:

interface ContactType {
    name: string
    phone: string
    avatar: Resource
}

这个接口定义了联系人的三个属性:姓名、电话号码和头像。其中头像使用Resource类型,表示资源引用。

2.2 数据准备

接下来,我们准备联系人数据:

private contacts:ContactType[] = [
    { name: '张三', phone: '138-0000-0001', avatar: $r('app.media.big30') },
    { name: '李四', phone: '138-0000-0002', avatar: $r('app.media.big29') },
    { name: '王五', phone: '138-0000-0003', avatar: $r('app.media.big28') },
    { name: '赵六', phone: '138-0000-0004', avatar: $r('app.media.big27') },
    { name: '钱七', phone: '138-0000-0005', avatar: $r('app.media.big26') },
    { name: '孙八', phone: '138-0000-0006', avatar: $r('app.media.big25') },
    { name: '周九', phone: '138-0000-0007', avatar: $r('app.media.big24') },
    { name: '吴十', phone: '138-0000-0008', avatar: $r('app.media.big23') },
]

我们创建了一个包含8个联系人的数组,每个联系人都有姓名、电话号码和头像资源。

2.3 页面结构设计

整个页面采用垂直布局,包含标题栏和联系人列表两部分:

build() {
    Column() {
        // 标题栏
        Row() {
            Text('联系人列表')
                .fontSize(24)
                .fontWeight(FontWeight.Bold)
        }
        .width('100%')
        .height(56)
        .padding({ left: 16 })
        .backgroundColor('#F1F3F5')

        // 联系人列表
        List() {
            // 列表内容
        }
        .width('100%')
        .layoutWeight(1)
        .divider({
            strokeWidth: 1,
            color: '#E5E5E5',
            startMargin: 72,
            endMargin: 16
        })
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#FFFFFF')
}

在这个结构中:

  • 使用Column作为根容器,占满整个屏幕
  • 顶部是一个Row容器,作为标题栏,包含标题文本
  • 下方是List组件,用于显示联系人列表
  • List组件通过layoutWeight(1)占据除标题栏外的所有空间

2.4 列表项实现

接下来,我们实现列表项的内容:

List() {
    ForEach(this.contacts, (contact:ContactType) => {
        ListItem() {
            Row() {
                // 头像
                Image(contact.avatar)
                    .width(40)
                    .height(40)
                    .borderRadius(20)
                    .margin({ right: 16 })

                // 联系人信息
                Column() {
                    Text(contact.name)
                        .fontSize(16)
                        .fontWeight(FontWeight.Medium)
                    Text(contact.phone)
                        .fontSize(14)
                        .fontColor('#666666')
                        .margin({ top: 4 })
                }
                .alignItems(HorizontalAlign.Start)
            }
            .width('100%')
            .padding({ left: 16, right: 16, top: 12, bottom: 12 })
        }
        .height(64)
    })
}

在这段代码中:

  1. 使用ForEach遍历contacts数组,为每个联系人创建一个ListItem
  2. 每个ListItem包含一个Row布局,用于水平排列头像和联系人信息
  3. 头像使用Image组件,设置为圆形(通过borderRadius实现)
  4. 联系人信息使用Column布局,包含姓名和电话号码两个Text组件
  5. 设置ListItem的高度为64像素,保证每个列表项高度一致

2.5 分割线设置

为了使列表项之间有明确的分隔,我们为List组件添加了分割线:

.divider({
    strokeWidth: 1,
    color: '#E5E5E5',
    startMargin: 72,
    endMargin: 16
})

分割线的配置说明:

属性 说明
strokeWidth 1 分割线宽度为1像素
color '#E5E5E5' 分割线颜色为浅灰色
startMargin 72 分割线左侧边距为72像素,与头像右侧对齐
endMargin 16 分割线右侧边距为16像素

三、完整代码解析

让我们来看一下完整的代码实现:

@Component
export struct BasicVerticalList {
    // 联系人数据
    private contacts:ContactType[] = [
        { name: '张三', phone: '138-0000-0001', avatar: $r('app.media.big30') },
        { name: '李四', phone: '138-0000-0002', avatar: $r('app.media.big29') },
        { name: '王五', phone: '138-0000-0003', avatar: $r('app.media.big28') },
        { name: '赵六', phone: '138-0000-0004', avatar: $r('app.media.big27') },
        { name: '钱七', phone: '138-0000-0005', avatar: $r('app.media.big26') },
        { name: '孙八', phone: '138-0000-0006', avatar: $r('app.media.big25') },
        { name: '周九', phone: '138-0000-0007', avatar: $r('app.media.big24') },
        { name: '吴十', phone: '138-0000-0008', avatar: $r('app.media.big23') },
    ]

    build() {
        Column() {
            // 标题栏
            Row() {
                Text('联系人列表')
                    .fontSize(24)
                    .fontWeight(FontWeight.Bold)
            }
            .width('100%')
            .height(56)
            .padding({ left: 16 })
            .backgroundColor('#F1F3F5')

            // 联系人列表
            List() {
                ForEach(this.contacts, (contact:ContactType) => {
                    ListItem() {
                        Row() {
                            // 头像
                            Image(contact.avatar)
                                .width(40)
                                .height(40)
                                .borderRadius(20)
                                .margin({ right: 16 })

                            // 联系人信息
                            Column() {
                                Text(contact.name)
                                    .fontSize(16)
                                    .fontWeight(FontWeight.Medium)
                                Text(contact.phone)
                                    .fontSize(14)
                                    .fontColor('#666666')
                                    .margin({ top: 4 })
                            }
                            .alignItems(HorizontalAlign.Start)
                        }
                        .width('100%')
                        .padding({ left: 16, right: 16, top: 12, bottom: 12 })
                    }
                    .height(64)
                })
            }
            .width('100%')
            .layoutWeight(1)
            .divider({
                strokeWidth: 1,
                color: '#E5E5E5',
                startMargin: 72,
                endMargin: 16
            })
        }
        .width('100%')
        .height('100%')
        .backgroundColor('#FFFFFF')
    }
}

3.1 代码结构分析

部分 说明
@Component 组件装饰器,表明这是一个自定义组件
private contacts 私有属性,存储联系人数据
build() 组件的构建函数,定义组件的UI结构
Column 根容器,垂直排列子元素
Row 标题栏容器,水平排列子元素
List 列表容器,用于展示联系人列表
ForEach 循环构建器,遍历联系人数据
ListItem 列表项容器,定义每个联系人的布局

3.2 样式设置分析

在这个案例中,我们使用了多种样式设置来美化界面:

  1. 尺寸设置

    • 使用width('100%')和height('100%')使组件占满父容器
    • 使用layoutWeight(1)使List组件占据剩余空间
    • 设置具体的像素值,如height(56)、width(40)等
  2. 边距和填充

    • 使用padding设置内边距
    • 使用margin设置外边距
  3. 颜色和背景

    • 设置背景颜色backgroundColor
    • 设置文本颜色fontColor
  4. 文本样式

    • 设置字体大小fontSize
    • 设置字体粗细fontWeight
  5. 特殊效果

    • 使用borderRadius设置圆角效果
    • 使用divider设置分割线

总结

在本篇教程中,我们学习了如何使用HarmonyOS NEXT的List和ListItem组件创建一个垂直方向的联系人列表。我们从数据模型定义、页面结构设计、列表项实现到分割线设置,全面讲解了垂直列表的实现过程。

收藏00

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

全栈若城

  • 0回答
  • 4粉丝
  • 0关注
相关话题