本文原创发布在华为开发者社区

介绍

本示例基于显式动画、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


鸿蒙场景化代码
1 声望0 粉丝