HarmonyOS 鸿蒙Next中如何使用PanGesture实现列表项的滑动删除?
HarmonyOS 鸿蒙Next中如何使用PanGesture实现列表项的滑动删除? 想实现一个类似邮件或待办事项应用的列表,用户可以向左滑动列表中的某一项,滑出后显示一个“删除”按钮。这个滑动操作应该如何监听?
使用场景
滑动删除是提升列表操作效率的经典交互模式。比如消息列表:左滑删除一条消息;待办事项:左滑标记完成或删除任务;文件管理器:左滑删除或分享文件等都是其经典的使用交互场景。
实现效果

完成思路
一、封装与复用:将滑动逻辑封装在SwipeItem组件中,使其成为一个可复用的UI单元。父组件只需关心数据和删除逻辑,无需关心滑动实现细节。
二、状态是桥梁:@State translateX是连接手势事件和UI视图的桥梁。手势改变状态,状态驱动UI更新。
三、@BuilderParam的妙用:使用@BuilderParam让SwipeItem组件更加灵活,父组件可以自由定义列表项内部的具体内容,实现了高内聚低耦合。
四、动画是点睛之笔:在onActionEnd中使用animateTo处理“收尾”工作,无论是自动滑出还是平滑回弹,都极大地提升了精致感。
完整代码
@Component
export struct SwipeItem {
// 子组件接收一个删除回调函数
onDelete?: () => void;
// 子组件接收要显示的内容,使用构建器函数 [@BuilderParam](/user/BuilderParam)
[@BuilderParam](/user/BuilderParam) content?: () => void;
// 1. 状态变量:控制列表项的水平偏移
[@State](/user/State) translateX: number = 0;
// 定义删除按钮的宽度
private readonly DELETE_BUTTON_WIDTH: number = 80;
// 定义触发删除的阈值
private readonly DELETE_THRESHOLD: number = -100;
build() {
Stack({ alignContent: Alignment.End }) {
// 删除按钮(在底层)
Button('删除')
.width(this.DELETE_BUTTON_WIDTH)
// .height('100%')
.backgroundColor(Color.Red)
.fontColor(Color.White)
.onClick(() => {
// 点击删除按钮时,执行删除动画并调用回调
animateTo({ duration: 300 }, () => {
this.translateX = -this.DELETE_BUTTON_WIDTH;
});
if (this.onDelete) {
this.onDelete();
}
})
// 列表项主内容(在顶层)
Row() {
// 使用 [@BuilderParam](/user/BuilderParam) 渲染父组件传入的内容
if (this.content) {
this.content()
}
}
.width('100%')
.height(60)
.backgroundColor('#FFFFFF')
.borderRadius(8)
// 2. 将位移与状态变量绑定
.translate({ x: this.translateX })
// 3. 绑定滑动手势
.gesture(
PanGesture({ fingers: 1, direction: PanDirection.Horizontal })
.onActionUpdate((event: GestureEvent) => {
// 实时更新偏移量,限制只能向左滑
this.translateX = Math.max(event.offsetX, -this.DELETE_BUTTON_WIDTH);
})
.onActionEnd(() => {
// 4. 手势结束时的判断与动画
if (this.translateX < this.DELETE_THRESHOLD) {
// 如果滑动距离超过阈值,则自动滑到删除按钮位置
animateTo({ duration: 200, curve: Curve.EaseOut }, () => {
this.translateX = -this.DELETE_BUTTON_WIDTH;
});
} else {
// 否则,回弹到原位
animateTo({ duration: 200, curve: Curve.EaseOut }, () => {
this.translateX = 0;
});
}
})
)
}
.width('100%')
.margin({ bottom: 8 })
}
}
// 文件名: Index.ets
import { SwipeItem } from './SwipeItem'; // 导入子组件
@Entry
@Component
struct Index {
// 父组件管理数据源
[@State](/user/State) messageList: string[] = [
'鸿蒙OS 5 正式发布',
'ArkTS 成为第一开发语言',
'元服务生态蓬勃发展',
'滑动删除交互体验极佳',
'学习鸿蒙,正逢其时'
];
build() {
Column() {
Text('消息列表 (左滑删除)')
.fontSize(24)
.fontWeight(FontWeight.Bold)
.margin({ top: 20, bottom: 20 })
List({ space: 8 }) {
ForEach(this.messageList, (item: string, index: number) => {
ListItem() {
// 5. 使用自定义的 SwipeItem 组件
SwipeItem({
// 传入删除逻辑的回调函数
onDelete: () => {
this.messageList.splice(index, 1);
},
// 使用 @Builder 传入自定义内容
content: () => {
this.ItemContent(item)
}
})
}
}, (item: string) => item)
}
.layoutWeight(1)
.width('90%')
.padding({ left: 10, right: 10 })
}
.width('100%')
.height('100%')
.backgroundColor('#F1F3F5')
}
// 定义列表项内容的构建器函数
@Builder ItemContent(text: string) {
Text(text)
.fontSize(18)
.fontColor('#333333')
.margin({ left: 15 })
}
}
更多关于HarmonyOS 鸿蒙Next中如何使用PanGesture实现列表项的滑动删除?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
在HarmonyOS Next中,使用PanGesture实现列表项滑动删除的步骤如下:
- 为列表项组件添加PanGesture手势识别器。
- 监听PanGesture的onActionUpdate事件,获取手指移动距离(offsetX)。
- 根据offsetX动态设置列表项的平移(translate)属性,实现跟随手指滑动的效果。
- 在onActionEnd事件中判断滑动距离,若超过阈值则触发删除操作,否则回弹复位。
- 结合条件渲染或状态变量控制删除按钮的显示与隐藏。
关键代码涉及手势事件处理和组件属性绑定。
在HarmonyOS Next中,可以使用PanGesture配合Row或List组件实现滑动删除效果。核心思路是为列表项容器添加PanGesture手势监听,通过手势偏移量动态控制内容布局。
以下是关键实现步骤:
-
布局结构:使用
Row组件作为列表项容器,内部包含两个子组件:主内容区域(如文本)和隐藏的删除按钮。通过justifyContent和alignItems控制布局。 -
手势监听:为主内容区域添加
PanGesture。.gesture( PanGesture() .onActionUpdate((event: GestureEvent) => { // 根据event.offsetX更新偏移量 }) .onActionEnd(() => { // 判断滑动距离,决定是否展开/收起删除按钮 }) ) -
状态管理:使用
@State装饰器定义偏移量变量,根据手势的offsetX动态更新。通过translate或position属性实现滑动动画。 -
滑动阈值:在
onActionEnd回调中判断滑动距离,若超过阈值则固定显示删除按钮,否则复位。 -
删除操作:为删除按钮绑定点击事件,通过
@Link或事件回调通知父组件删除对应数据项。
注意:在List中使用时,需确保每个列表项的偏移状态独立管理,避免联动。可结合ListItem和SwipeAction组件简化实现,后者为滑动操作提供了封装好的布局和动画。

