写点什么

HarmonyOS 实战:List 拖拽位置交换的多种实现方式

作者:IT小码哥
  • 2025-06-16
    北京
  • 本文字数:1339 字

    阅读完需:约 4 分钟

背景

在最近日常工作中,遇到需要实现拖拽列表中的元素进行位置交换的需求。第一时间翻看了鸿蒙官方文档,发现官方只给 Grid 提供了 Item 交换位置的实现方式,然而 List 并没有提供,于是需要自己动手去实现。本篇文章详细介绍了两种不同的方式去实现 List 的位置交换。

技术实现

方式一

使用列表的手势事件实现位置交换。

  1. 先实现 List 的 onItemDragStart 方法。该方法表示拖拽列表元素时触发。

.onItemDragStart((event: ItemDragInfo, index: number) => {  })
复制代码


event:表示拖拽点坐标,index:表示当前位置元素的下标。

  1. 然后实现列表的 onItemDrop 方法,表示拖拽结束时回调。

.onItemDrop((event:ItemDragInfo,itemIndex:number,insertIndex:number,isSuccess:boolean)=>{ })
复制代码


event:表示当前交换的位置坐标,itemIndex:表示拖拽前元素的下标,insertIndex:表示需要交换位置元素的下标,isSuccess:表示拖拽是否结束。

  1. 为了实现更好的交互效果,在拖拽开始的地方也就是 onItemDragStart 方法里面,添加拖拽时元素显示的画面,作为返回值。

Column() {  Text(text.name)    .fontSize(15)    .backgroundColor(Color.Blue)    .width("100%")    .height(80)    .borderRadius(10)    .textAlign(TextAlign.Center)}.padding(10)
复制代码
  1. 最后在交换拖拽时,交换两个元素的位置即可,即在 onItemDrop 中实现。

if (!isSuccess || (itemIndex||insertIndex) >= this.arr.length) {  return}let temp = this.list[itemIndex];this.list[itemIndex] = this.list[insertIndex];this.list[insertIndex] = temp;
复制代码

首先需要判断拖拽手势是否结束,同时两个下标是否发生数组越界。条件满足后进行元素位置交换。注意 list 必须被 @State 或 @Local 修饰。

方式二

使用列表和元素共同实现元素交换。

  1. 首先实现元素的 onDragStart 方法,表示元素被开始拖拽。

.onDragStart((event: DragEvent, extraParams: string) => { })
复制代码

event:表示元素在屏幕上的坐标信息,extraParams:表示元素被选中时的下标。

  1. 接着实现列表的 onDrop 方法,表示列表被拖拽时触发。

.onDrop((event: DragEvent, extraParams: string) =>{  })
复制代码

event:表示元素在屏幕上的坐标信息,extraParams:表示拖拽过程中列表元素的位置下标。

  1. 在 onDragStart 方法中使用局部变量保存拖拽前元素的下标。同时返回被拖拽元素的 View,这里定义一个 SwitchItemPosition 类用来解析 extraParams 得到拖拽前元素的下标。

// extraParams :{"selectedIndex":5}this.dragIndex = (JSON.parse(extraParams) as SwitchItemPosition).selectedIndex;return this.pixelMapBuilder(this.listArr[this.dragIndex])
复制代码
  1. 在 onDrop 方法中解析出元素被拖拽的最终位置,然后进行元素位置交换,注意判断数组越界。

let insertIndex: number = (JSON.parse(extraParams) as SwitchItemPosition).insertIndex; if (insertIndex >= this.list.length) {  return;}let temp = this.list[itemIndex];this.list[itemIndex] = this.list[insertIndex];this.list[insertIndex] = temp;
复制代码

总结

在实际的开发实现时,通过对列表元素的回调方法的研究与分析,不断的重复尝试,最终实现了列表元素的位置交换,当然目前的实现方案仍有瑕疵,缺少交互动画,

后续会对这些问题进行完善,看完文章,你学会了吗?

用户头像

IT小码哥

关注

还未添加个人签名 2021-04-29 加入

还未添加个人简介

评论

发布
暂无评论
HarmonyOS实战:List拖拽位置交换的多种实现方式_harmony_IT小码哥_InfoQ写作社区