当前位置: 首页 > news >正文

鸿蒙开发中的List组件详解

目录

引言

1.List组件基础

2.List接口参数

 1.space

2.initialIndex

3.scroller

3.ListView的属性        

1.listDirection

2.lanes

3.divider

4.scrollBar

4.布局与约束

5.ListItem生命周期

1.使用ForEach创建ListItem

2.使用LazyForEach创建ListItem        

3.使用Repeat创建ListItem

1.使用virtualScroll

2.不使用virtualScroll

6.List的使用场景

1. 最简单的List

2. 自定义组件

3. 滚动控制

高级特性

1. 分组列表

2. 懒加载

3. 下拉刷新与上拉加载

性能优化技巧

常见问题解决

结语


引言

        在鸿蒙(HarmonyOS)应用开发中,List组件是最常用的UI组件之一,用于展示垂直滚动的列表数据。本文将详细介绍List组件的特性、使用方法以及一些实用技巧。

1.List组件基础

        列表是一种复杂的容器,当列表项达到一定数量,内容超过屏幕大小时,可以自动提供滚动功能。它适合用于呈现同类数据类型或数据类型集,例如图片和文本。在列表中显示数据集合是许多应用程序中的常见要求(如通讯录、音乐列表、购物清单等)。

        List是鸿蒙OS中用于展示垂直滚动列表的容器组件,具有以下特点:

  • 高性能的列表渲染

  • 支持大数据量的流畅滚动

  • 内置多种布局和交互效果

  • 支持分组和多种列表项样式

2.List接口参数

    当我们创建 List 的时候,有三个默认可选参数,分别是 space、initialIndex、scroller。

    我们分别看看他们的属性。

 1.space

        space 用来设置子组件主轴方向的间隔。

 图1.space属性

2.initialIndex

        设置当前 List初次加载的时候,初始 item 的索引值。

图2.修改初次加载显示的数据元素下标

3.scroller

        可以滚动组件的控制器。

        我们可以调用scroll的相关方法处理List。

        例如我们可以通过下面的代码把List滚动到底部

          Button("滚动到底部").onClick(()=>{this.scroller.scrollEdge(Edge.Bottom)})

3.ListView的属性        

1.listDirection

        设置List组件的排列方向。

        listDirection是Axis类型的枚举,定义如下:

declare enum Axis {
    Vertical,
    Horizontal
}        

        默认值为Axis.Vertical,方向为纵向。

        Axis.Horizontal方向为横向。

2.lanes

        设置List组件的布局列数或者行数。

        lanes是鸿蒙(HarmonyOS)中List组件的一个重要属性,用于控制列表在水平方向上的布局方式,特别适用于需要多列布局的场景。通过设置lanes属性,可以让List组件中的列表项以网格形式排列,而不是传统的单列垂直排列。

3.divider

        设置ListItem分割线样式,默认无分割线。

4.scrollBar

        设置滚动条状态。

        BarState.AutoAuto:按需显示

        BarState.AutoOff:不显示

        BarState.AutoOn:常驻显示

4.布局与约束

        列表作为一种容器,会自动按其滚动方向排列子组件,向列表中添加组件或从列表中移除组件会重新排列子组件。

        如下图所示,在垂直列表中,List按垂直方向自动排列ListItemGroup或ListItem。

ListItemGroup用于列表数据的分组展示,其子组件也是ListItem。ListItem表示单个列表项,可以包含单个子组件。

图3.List、ListItemGroup和ListItem组件关系

5.ListItem生命周期

1.使用ForEach创建ListItem

        List组件创建时,所有ListItem将会被创建。显示区域内的ListItem在首帧进行布局,预加载范围内的ListItem在空闲时完成布局。预加载范围之外的ListItem仅创建ListItem自身,ListItem其内部的子组件不会被创建。

        当List组件滑动时,进入预加载及显示区域的ListItem将会创建其内部的子组件并完成布局,而滑出预加载及显示区域的ListItem将不会被销毁。

图4.ForEach创建ListItem

2.使用LazyForEach创建ListItem        

        List组件创建时,显示区域中的ListItem会被创建与布局。预加载范围内的ListItem在空闲时创建与布局,但是不会被挂载到组件树上。预加载范围外的ListItem则不会被创建。

        当List组件滑动时,进入预加载及显示区域的ListItem将被创建与布局,创建ListItem过程中,若ListItem内部如果包含@Reusable标记的自定义组件,则会优先从缓存池中复用。滑出预加载及显示区域的ListItem将被销毁,其内部若含@Reusable标记的自定义组件,则会被回收并加入缓存池。

图5.LazyForEach创建ListItem的生命周期

3.使用Repeat创建ListItem

1.使用virtualScroll

        List组件创建时,显示区域内的ListItem将被创建和布局。预加载范围内的ListItem在空闲时创建和布局,并且挂载至组件树上。预加载范围外的ListItem则不会被创建。

        当List组件滑动时,进入预加载及显示区域的ListItem,将从缓存池中获取ListItem并复用及布局,若缓存池中无ListItem,则会新创建并布局。滑出预加载及显示区域的ListItem会将被回收至缓存池。

        图6.Repeat使用virtualScroll创建ListItem的生命周期

2.不使用virtualScroll

        List组件创建时,所有ListItem均被创建。显示区域内的ListItem在首帧完成布局,预加载范围内的ListItem在空闲时完成布局。预加载范围外的ListItem不会进行布局。

        当List组件滑动时,进入预加载及显示区域的ListItem将进行布局。滑出预加载及显示区域的ListItem不会销毁。

图7.Repeat不使用virtualScroll创建ListItem的生命周期

1.listDirection

1.listDirection

// 示例代码:基本List使用
import { List, ListItem } from '@ohos/arkui';@Entry
@Component
struct MyList {private data: string[] = ['苹果', '香蕉', '橙子', '葡萄', '西瓜']build() {Column() {List({ space: 20 }) {ForEach(this.data, (item: string) => {ListItem() {Text(item).fontSize(20).margin({ left: 15 })}})}.width('100%').height('100%')}}
}

6.List的使用场景

1. 最简单的List

        在最简单的列表形式中,List静态地创建其列表项ListItem的内容。

        当我们ListView的ListItem只有一个组件的时候,我们使用下面的代码即可实现一个简单的列表。

@Entry
@Component
struct CityList {build() {NavDestination(){List() {ListItem(){Text('北京').fontSize(24)}ListItem(){Text('上海').fontSize(24)}ListItem(){Text('杭州').fontSize(24)}}    .backgroundColor('#FFF1F3F5').alignListItem(ListItemAlign.Center)}.title("List实现城市列表")}
}

        效果图如下:

图8.最简单的List

@State private messages: Message[] = [{ id: 1, content: '你好鸿蒙' },{ id: 2, content: 'List组件学习' },// 更多数据...
];List() {ForEach(this.messages, (item: Message) => {ListItem() {Text(item.content)}})
}

2. 自定义组件

        因此,如果ListItem是由多个组件元素组成的,则需要将这多个元素组合到一个容器组件内或组成一个自定义组件。

        例如我们要实现一个通讯录联系人页面:

图9.联系人列表

        如上图所示,联系人列表的列表项中,每个联系人都有头像和名称。此时,需要将Image和Text封装到一个Row容器内。

List() {ListItem() {Row() {// app.media.iconE为自定义资源Image($r('app.media.iconE')).width(40).height(40).margin(10)Text('小明').fontSize(20)}}ListItem() {Row() {// app.media.iconF为自定义资源Image($r('app.media.iconF')).width(40).height(40).margin(10)Text('小红').fontSize(20)}}
}

3. 滚动控制

private scroller: Scroller = new Scroller()List({ scroller: this.scroller }) {// 列表内容
}// 滚动到指定位置
this.scroller.scrollTo({ x: 0, y: 100 })

高级特性

1. 分组列表

List() {ForEach(this.groupData, (group: Group) => {ListItemGroup({ header: this.GroupHeader(group.name) }) {ForEach(group.items, (item: Item) => {ListItem() {Text(item.name)}})}})
}

2. 懒加载

List() {LazyForEach(this.dataSource, (item: Item) => {ListItem() {Text(item.name)}})
}

3. 下拉刷新与上拉加载

List({ controller: this.listController }) {// 列表内容
}
.onRefresh(() => {// 下拉刷新逻辑
})
.onReachEnd(() => {// 上拉加载更多
})

性能优化技巧

  1. 复用列表项​:确保ListItem的结构尽可能简单,提高复用率

  2. 避免复杂计算​:在列表渲染中避免复杂的计算和频繁的UI更新

  3. 使用LazyForEach​:对于大数据集,使用LazyForEach代替ForEach

  4. 图片懒加载​:列表中的图片使用懒加载技术

常见问题解决

  1. 列表滚动卡顿​:

    • 检查是否有过多的UI更新

    • 确保使用了正确的数据绑定方式

    • 考虑分页加载数据

  2. 列表项点击无响应​:

    • 检查是否添加了.onClick事件

    • 确保没有其他组件遮挡了点击区域

  3. 列表数据显示异常​:

    • 检查数据源是否正确更新

    • 确认ForEach或LazyForEach的key值唯一且稳定

结语

List组件是鸿蒙应用开发中不可或缺的重要组件,掌握其使用方法和优化技巧对于构建流畅的用户界面至关重要。通过本文的介绍,希望您能更高效地使用List组件,为您的鸿蒙应用带来更好的用户体验。

在实际开发中,建议多参考鸿蒙官方文档和示例代码,不断实践和优化您的列表实现。

http://www.xdnf.cn/news/1341505.html

相关文章:

  • 机器学习-集成算法
  • Django的生命周期
  • 项目1总结其三(图片上传功能)
  • leetcode-python-242有效的字母异位词
  • 阿里巴巴推出Qoder:面向真实软件开发的智能编程平台
  • 计算机视觉(opencv)实战六——图像形态学(腐蚀、膨胀、开运算、闭运算、梯度、顶帽、黑帽)
  • 计算机视觉第一课opencv(三)保姆级教学
  • 大语言模型原理(Transformer架构)
  • c# 和 c++ 怎样结合
  • Chrome 插件开发实战:从入门到进阶
  • Docker:安装配置
  • 【框架篇二】FastAPI路由与请求处理
  • Linux 网络命令大全
  • uniapp 自定义组件封装、easycom匹配规则
  • 2025-08-21 Python进阶4——错误和异常
  • 用 Python 写的自动化测试 WPF 程序的一个案例
  • 【GaussDB】使用gdb定位GaussDB编译package报错
  • Spring Boot整合Amazon SNS实战:邮件订阅通知系统开发
  • 第三阶段数据库-6:sql中函数,多表查询,运算符,索引,约束
  • 我从零开始学微积分(2)- 函数与图形
  • 与森马品牌代言人王安宇专注日常力量,再启新常服故事
  • Qt二维码生成器项目开发教程 - 从零开始构建专业级QR码生成工具
  • 精算中的提升曲线(Lift Curve)与机器学习中的差别
  • Design Compiler:逻辑库名与逻辑库文件名及其指定方式
  • 交易高光时刻-01
  • langgraph快速搭建agent后端和react前端
  • springboot 启动后get请求任意接口地址会跳到登录页
  • 【TrOCR】模型预训练权重各个文件解读
  • 【Java集合】List,Map,Set-详细讲解
  • ODDR实现多bit单边沿采样数据转为多bit双沿采样数据