Harmony开发 List、Grid拖动自定义排序实现

发布于:2025-05-18 ⋅ 阅读:(18) ⋅ 点赞:(0)

1. Harmony开发 List、Grid拖动自定义排序实现

1.1. List拖动功能

  本示例基于显式动画、List组件实现了ListItem的上下拖动、ListItem切换以及ListItem插入的效果。
在这里插入图片描述
  实现思路:List手势拖动

@Entry
@Component
struct ListDragPage {
   
  @State private arr: string[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14].map((value) => value.toString())
  private listScroller: ListScroller = new ListScroller();
  private dragIndex: number = -1
  private originDragIndex: number = -1
  @State itemOffsetList: number[] = []
  private itemHeight: number = 100
  private listMargin: number = 10
  private itemTotalHeight: number = 110
  // dragItem距离List组件顶部的距离
  private dragOffsetY: number = 0
  // dragItem相对于List滚动顶部的距离
  private relativeOffsetY: number = 0
  // List组件能滑动的最大距离
  listMaxScrollOffsetY: number = 0
  // List组件开始拖动时的偏移
  originListOffsetY: number = 0
  // list组件规格
  private listArea: Area = {
   
    width: 0,
    height: 0,
    position: {
   },
    globalPosition: {
   }
  }

  aboutToAppear(): void {
   
    this.itemOffsetList = new Array<number>(this.arr.length)
  }

  initState() {
   
    for (let i = 0; i < this.itemOffsetList.length; i++) {
   
      this.itemOffsetList[i] = 0
    }
    this.dragIndex = -1
    this.originDragIndex = -1
    this.dragOffsetY = 0
    this.originListOffsetY = this.listScroller.currentOffset().yOffset
  }

  startDragItem(dragIndex: number) {
   
    this.initState()
    animateTo({
    curve: Curve.Linear }, () => {
   
      this.dragIndex = dragIndex
      this.originDragIndex = dragIndex
    })
  }

  increaseDragIndex(eventOffsetY: number) {
   
    let tmp = this.arr.splice(this.dragIndex, 1)
    this.arr.splice(this.dragIndex + 1, 0, tmp[0])
    this.dragIndex = this.dragIndex + 1
    this.itemOffsetList[this.dragIndex] =
      eventOffsetY - (this.dragIndex - this.originDragIndex) * this.itemTotalHeight +
      this.listScroller.currentOffset().yOffset - this.originListOffsetY
    this.itemOffsetList[this.dragIndex - 1] = this.itemTotalHeight
    animateTo({
    curve: Curve.Sharp, duration: 100 }, () => {
   
      this.itemOffsetList[this.dragIndex - 1] = 0
    })
  }

  decreaseDragIndex(eventOffsetY: number) {
   
    let tmp = this.arr.splice(this.dragIndex, 1)
    this.arr.splice(this.dragIndex - 1, 0, tmp[0])
    this.dragIndex = this.dragIndex - 1
    this.itemOffsetList[this.dragIndex] =
      eventOffsetY - (this.dragIndex - this.originDragIndex) * this.itemTotalHeight +
      this.listScroller.currentOffset().yOffset - this.originListOffsetY
    this.itemOffsetList[this.dragIndex + 1] = -this.itemTotalHeight
    animateTo({
    curve: Curve.Sharp, duration: 100 }, () => {
   
      this.itemOffsetList[this.dragIndex + 1] = 0
    })
  }

  cancelDrag() {
   
    this.initState()
  }

  endDragItem() {
   
    animateTo({
    curve: Curve.Sharp, duration: 100 }, () => {
   
      this.initState()
    })
  }

  build() {
   
    Column() {
   
      List({
     space: this.listMargin

网站公告

今日签到

点亮在社区的每一天
去签到