HarmonyOS ArkUI List 侧滑删除与分组粘性标题:2 个实战案例解析
·
HarmonyOS ArkUI List 侧滑删除与分组粘性标题实战指南
在移动应用开发中,列表(List)是最常用的UI组件之一。HarmonyOS的ArkUI框架提供了功能强大的List组件,支持多种高级交互效果。本文将重点介绍两个提升用户体验的核心功能:侧滑删除(swipeAction)和分组粘性标题(sticky),并通过两个完整案例演示如何在实际项目中应用这些特性。
1. List组件基础与高级特性概述
List组件是HarmonyOS中用于展示结构化数据的滚动容器,具有以下核心特点:
- 自动滚动 :当内容超出可视区域时自动提供滚动功能
- 灵活布局 :支持垂直和水平两种滚动方向
- 高效渲染 :提供条件渲染、循环渲染和懒加载等优化手段
- 丰富交互 :支持点击、长按、侧滑等多种交互方式
在通讯录、消息列表、商品展示等场景中,List组件的高效实现直接影响用户体验。我们特别关注的两个高级特性:
// 基础List结构示例
List() {
ForEach(this.items, (item) => {
ListItem() {
// 列表项内容
}
})
}
1.1 侧滑删除实现原理
侧滑删除是现代移动应用中常见的交互模式,允许用户通过水平滑动列表项来触发删除或其他操作。ArkUI通过 swipeAction 属性实现这一功能:
- Builder模式 :使用@Builder构建侧滑操作按钮
- 方向控制 :可配置左侧(end)或右侧(start)滑动
- 事件绑定 :为操作按钮绑定点击事件处理逻辑
1.2 分组粘性标题工作机制
分组列表中的粘性标题(sticky header)在滚动时会固定在列表顶部,直到下一组标题将其顶替。这种设计:
- 提升内容组织结构可视性
- 方便用户快速定位到特定分组
- 通过
ListItemGroup和sticky属性协同实现
2. 通讯录分组列表实现
下面我们实现一个带粘性标题的分组通讯录列表,包含以下功能:
- 按字母分组联系人
- 粘性标题效果
- 快速返回顶部按钮
2.1 数据结构设计
首先定义联系人和分组的数据结构:
class Contact {
key: string = util.generateRandomUUID(true);
name: string;
avatar: Resource;
constructor(name: string, avatar: Resource) {
this.name = name;
this.avatar = avatar;
}
}
// 分组数据示例
private groups = [
{
title: "A",
contacts: [
new Contact("Alice", $r("app.media.avatar1")),
new Contact("Andy", $r("app.media.avatar2"))
]
},
{
title: "B",
contacts: [
new Contact("Bob", $r("app.media.avatar3")),
new Contact("Betty", $r("app.media.avatar4"))
]
}
];
2.2 分组标题构建器
使用@Builder创建分组标题组件:
@Builder
groupHeader(title: string) {
Text(title)
.fontSize(20)
.backgroundColor('#F5F5F5')
.width('100%')
.padding(10)
}
2.3 完整列表实现
组合List、ListItemGroup和sticky属性:
@Entry
@Component
struct ContactsList {
private scroller: Scroller = new Scroller();
build() {
Stack({ alignContent: Alignment.BottomEnd }) {
List({ space: 10, scroller: this.scroller }) {
ForEach(this.groups, (group) => {
ListItemGroup({ header: this.groupHeader(group.title) }) {
ForEach(group.contacts, (contact) => {
ListItem() {
Row() {
Image(contact.avatar)
.width(40).height(40).margin(10)
Text(contact.name).fontSize(18)
}
.width('100%')
}
})
}
})
}
.width('100%')
.sticky(StickyStyle.Header) // 启用粘性标题
// 返回顶部按钮
Button() {
Image($r("app.media.arrow_up"))
.width(30).height(30)
}
.onClick(() => {
this.scroller.scrollToIndex(0)
})
.margin({ bottom: 30, right: 20 })
}
}
}
提示 :粘性标题效果需要同时满足三个条件:
- 使用ListItemGroup分组
- 为List设置sticky属性
- 为ListItemGroup提供header构建器
3. 消息列表侧滑删除实现
接下来我们实现一个消息列表,支持左滑显示删除按钮。
3.1 消息数据结构
class Message {
key: string = util.generateRandomUUID(true);
sender: string;
content: string;
time: string;
unread: boolean;
constructor(sender: string, content: string, time: string) {
this.sender = sender;
this.content = content;
this.time = time;
this.unread = Math.random() > 0.5;
}
}
@State messages: Message[] = [
new Message("张三", "晚上一起吃饭吗?", "10:30"),
new Message("李四", "项目文档已更新", "09:15"),
// 更多消息...
];
3.2 侧滑操作构建器
创建删除按钮的Builder:
@Builder
deleteButton(index: number) {
Button() {
Image($r("app.media.delete"))
.width(25).height(25)
}
.width(80)
.height('100%')
.backgroundColor(Color.Red)
.onClick(() => {
this.messages.splice(index, 1);
})
}
3.3 完整消息列表实现
@Entry
@Component
struct MessageList {
build() {
List({ space: 5 }) {
ForEach(this.messages, (message, index) => {
ListItem() {
Row() {
// 未读标记
if (message.unread) {
Circle({ width: 8, height: 8 })
.fill(Color.Blue)
.margin({ right: 10 })
}
Column() {
Row() {
Text(message.sender)
.fontSize(18)
.fontWeight(FontWeight.Bold)
Text(message.time)
.fontSize(14)
.fontColor('#999')
.margin({ left: 10 })
}
.width('100%')
.justifyContent(FlexAlign.SpaceBetween)
Text(message.content)
.fontSize(16)
.margin({ top: 5 })
}
.layoutWeight(1)
}
.padding(10)
.width('100%')
}
.swipeAction({ end: this.deleteButton(index) }) // 右侧滑出删除按钮
})
}
.width('100%')
.height('100%')
.divider({
strokeWidth: 1,
color: '#EEE',
startMargin: 60,
endMargin: 0
})
}
}
4. 性能优化与最佳实践
在实现复杂列表时,需要注意以下性能优化点:
4.1 列表渲染优化
| 优化策略 | 实现方式 | 适用场景 |
|---|---|---|
| 键值生成 | 为ForEach提供稳定唯一的key | 所有动态列表 |
| 懒加载 | 使用LazyForEach替代ForEach | 超长列表 |
| 预渲染 | 设置cachedCount | 快速滚动场景 |
| 轻量组件 | 简化ListItem内部结构 | 复杂列表项 |
4.2 交互体验提升技巧
- 视觉反馈 :为侧滑操作添加适当的动画效果
- 撤销机制 :删除操作后提供撤销选项
- 分组索引 :添加字母索引条方便快速导航
- 加载更多 :滚动到底部时自动加载更多数据
// 懒加载示例
List() {
LazyForEach(this.dataSource, (item) => {
ListItem() {
// 列表项内容
}
})
}
.cachedCount(5) // 预渲染5个项目
通过合理运用ArkUI List组件的高级特性,可以显著提升应用的交互体验和视觉表现。本文的两个案例展示了如何在实际项目中实现这些功能,开发者可以根据具体需求进行调整和扩展。
更多推荐


所有评论(0)