HarmonyOS 鸿蒙Next实现List拖动功能示例代码

HarmonyOS 鸿蒙Next实现List拖动功能示例代码

介绍

本示例基于显式动画、List组件实现了ListItem的上下拖动、ListItem切换以及ListItem插入的效果。

实现List拖动功能源码链接

效果预览

图片名称

使用说明

运行项目前,请执行 ohpm install @ohos/hamock,下载hamock依赖。

实现思路

List手势拖动:

LongPressGesture({
  fingers: 1,
  repeat: false,
  duration: 100
})
  .onAction(() => {
    this.startDragItem(index)
  }),
PanGesture()
  .onActionStart(() => {
    this.startDragItem(index)
  })
  .onActionUpdate((event: GestureEvent) => {
    this.dragOffsetY = event.offsetY - (this.dragIndex - this.originDragIndex) * this.itemTotalHeight +
    this.listScroller.currentOffset().yOffset - this.originListOffsetY
    // 限制dragOffsetY上下界
    let maxOffsetY = (this.arr.length - this.dragIndex - 1) * this.itemTotalHeight - this.listMargin
    let minOffsetY = -this.dragIndex * this.itemTotalHeight + this.listMargin
    this.dragOffsetY = Math.min(maxOffsetY, this.dragOffsetY)
    this.dragOffsetY = Math.max(minOffsetY, this.dragOffsetY)
    this.relativeOffsetY = this.dragOffsetY + this.dragIndex * this.itemTotalHeight + this.itemHeight / 2
    this.itemOffsetList[this.dragIndex] = this.dragOffsetY
    let fingerInfo = event.fingerList[0]
    let clickPercentY =
      (fingerInfo.globalY - Number(this.listArea.globalPosition.y)) / Number(this.listArea.height)
    if (clickPercentY > 0.8 && !this.listScroller.isAtEnd()) {
      let scrollVelocity = clickPercentY > 0.9 ? 4 : 2
      if (this.listMaxScrollOffsetY - this.listScroller.currentOffset().yOffset > scrollVelocity + 5) {
        this.listScroller.scrollTo({
          xOffset: 0,
          yOffset: this.listScroller.currentOffset().yOffset += scrollVelocity
        })
      }
    } else if (clickPercentY < 0.2 && this.listScroller.currentOffset().yOffset >= 0) {
      let scrollVelocity = clickPercentY < 0.1 ? 4 : 2
      if (this.listScroller.currentOffset().yOffset > scrollVelocity + 5) {
        this.listScroller.scrollTo({
          xOffset: 0,
          yOffset: this.listScroller.currentOffset().yOffset -= scrollVelocity
        })
      }
    }
    // 获取当前滑动到的index
    let insertIndex = Math.trunc(this.relativeOffsetY / this.itemTotalHeight)
    if (this.dragIndex < insertIndex) {
      this.increaseDragIndex(event.offsetY)
    } else if (this.dragIndex > insertIndex) {
      this.decreaseDragIndex(event.offsetY)
    }
  })
  .onActionEnd(() => {
    this.endDragItem()
  })
.onCancel(() => {
  this.cancelDrag()
})

具体代码参考Index


更多关于HarmonyOS 鸿蒙Next实现List拖动功能示例代码的实战教程也可以访问 https://www.itying.com/category-93-b0.html

1 回复

更多关于HarmonyOS 鸿蒙Next实现List拖动功能示例代码的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS(鸿蒙Next)中,实现List拖动功能可以通过List组件和DragEvent事件来实现。以下是一个简单的示例代码,展示如何在鸿蒙Next中实现List项的拖动功能。

import { List, ListItem, DragEvent } from '@ohos.arkui';

class DragListExample {
  private listData: string[] = ['Item 1', 'Item 2', 'Item 3', 'Item 4'];

  build() {
    List({ space: 10 }) {
      ForEach(this.listData, (item: string, index: number) => {
        ListItem() {
          Text(item)
            .fontSize(20)
            .padding(10)
            .backgroundColor('#f0f0f0')
            .onDragStart((event: DragEvent) => {
              event.setData('text/plain', item);
            })
            .onDragEnter((event: DragEvent) => {
              // 处理拖动进入事件
            })
            .onDragOver((event: DragEvent) => {
              // 处理拖动悬停事件
            })
            .onDragLeave((event: DragEvent) => {
              // 处理拖动离开事件
            })
            .onDrop((event: DragEvent) => {
              const draggedItem = event.data.getText('text/plain');
              const droppedItem = item;
              this.swapItems(draggedItem, droppedItem);
            });
        }
      });
    }
    .width('100%')
    .height('100%');
  }

  private swapItems(draggedItem: string, droppedItem: string) {
    const draggedIndex = this.listData.indexOf(draggedItem);
    const droppedIndex = this.listData.indexOf(droppedItem);
    if (draggedIndex !== -1 && droppedIndex !== -1) {
      [this.listData[draggedIndex], this.listData[droppedIndex]] = [this.listData[droppedIndex], this.listData[draggedIndex]];
    }
  }
}

在这个示例中,我们创建了一个List组件,并使用ForEach遍历listData数组生成ListItem。每个ListItem中的Text组件都绑定了onDragStart事件,用于在拖动开始时设置数据。onDrop事件用于处理拖动释放后的逻辑,即交换两个列表项的位置。通过swapItems方法,我们实现了列表项的拖动和重新排序功能。

回到顶部