HarmonyOS 鸿蒙Next Grid组件编辑模式实现拖拽

发布于 1周前 作者 yuanlaile 最后一次编辑是 5天前 来自 鸿蒙OS

HarmonyOS 鸿蒙Next Grid组件编辑模式实现拖拽

grid设置不规则GridItem的条件下,editMode模式下的拖拽就无法正常使用了,如附件这种场景,麻烦指导一下。

1 回复

视频附件中播放的是可以拖拽, 请提供,grid设置不规则GridItem的条件下,editMode模式下的拖拽就无法正常使用了的视频附件,

最好提供一个最小化demo,以便分析问题

可以参考以下demo


// xxx.ets

@Entry

@Component

struct GridItemExample {

  @State numbers: number[] = []

  @State dragItem: number = -1

  @State scaleItem: number = -1

  @State item: number = -1

  @State offsetX: number = 0

  @State offsetY: number = 0

  private FIX_VP_X: number = 108

  private FIX_VP_Y: number = 120

  @State moveIndex:number = -1

  scroller: Scroller = new Scroller()

  layoutOptions1: GridLayoutOptions = {

    regularSize: [1, 1],

    irregularIndexes: [0]

  }

  aboutToAppear() {

    for (let i = 1; i <= 11; i++) {

      this.numbers.push(i)

    }

  }

  itemMove(index: number, newIndex: number): void {

    let tmp = this.numbers.splice(index, 1)

    this.numbers.splice(newIndex, 0, tmp[0])

  }

  build() {

    Column() {

      Grid(this.scroller, this.layoutOptions1) {

        ForEach(this.numbers, (item: number) => {

          GridItem() {

            Text(item + '')

              .fontSize(16)

              .width('100')

              .textAlign(TextAlign.Center)

              .height(100)

              .borderRadius(10)

              .backgroundColor(0xFFFFFF)

              .shadow(this.scaleItem == item ? { radius: 70, color: '#15000000', offsetX: 0, offsetY: 0 } :

                { radius: 0, color: '#15000000', offsetX: 0, offsetY: 0 })

              .animation({ curve: Curve.Sharp, duration: 300 })

              .scale({ x: this.scaleItem == item ? 1.05 : 1, y: this.scaleItem == item ? 1.05 : 1 })

              .zIndex(this.dragItem == item ? 1 : 0)

              .translate(this.dragItem == item ? { x: this.offsetX, y: this.offsetY } : { x: 0, y: 0 })

              .gesture(

                // 以下组合手势为顺序识别,当长按手势事件未正常触发时则不会触发拖动手势事件

                GestureGroup(GestureMode.Sequence,

                  LongPressGesture({ repeat: true })

                    .onAction((event?: GestureEvent) => {

                      animateTo({ curve: Curve.Friction, duration: 300 }, () => {

                        this.scaleItem = item

                      })

                    })

                    .onActionEnd(() => {

                      animateTo({ curve: Curve.Friction, duration: 300 }, () => {

                        this.scaleItem = -1

                      })

                    }),

                  PanGesture({ fingers: 1, direction: null, distance: 0 })

                    .onActionStart(() => {

                      this.dragItem = item

                    })

                    .onActionUpdate((event: GestureEvent) => {

                      this.offsetY = event.offsetY

                      this.offsetX = event.offsetX

                      let index = this.numbers.indexOf(this.dragItem)

                      let xIndex = Math.round(this.offsetX/this.FIX_VP_X)

                      let yIndex = Math.round(this.offsetY/this.FIX_VP_Y)

                      let insertIndex = index + yIndex * 3 + xIndex

                      if(insertIndex !== this.moveIndex){

                        this.moveIndex = insertIndex

                      }

                    })

                    .onActionEnd(() => {

                      animateTo({ curve: curves.interpolatingSpring(0, 1, 400, 38) }, () => {

                        let index = this.numbers.indexOf(this.dragItem)

                        if(index === 0){

                          this.moveIndex --

                        }

                        if(this.moveIndex < 0){

                          this.moveIndex = 0

                        }

                        if(this.moveIndex > this.numbers.length - 1){

                          this.moveIndex = this.numbers.length - 1

                        }

                        this.itemMove(index,this.moveIndex)

                        this.dragItem = -1

                      })

                      animateTo({

                        curve: curves.interpolatingSpring(14, 1, 170, 17), delay: 150

                      }, () => {

                        this.scaleItem = -1

                      })

                    })

                )

                  .onCancel(() => {

                    animateTo({ curve: curves.interpolatingSpring(0, 1, 400, 38) }, () => {

                      this.dragItem = -1

                    })

                    animateTo({

                      curve: curves.interpolatingSpring(14, 1, 170, 17)

                    }, () => {

                      this.scaleItem = -1

                    })

                  })

              )

          }

          .padding(10)

        }, (item: number) => item.toString())

      }

      .width('90%')

      .editMode(true)

      .scrollBar(BarState.Off)

      .columnsTemplate("1fr 1fr 1fr")

    }.width('100%').height('100%').backgroundColor('#0D182431').padding({ top: 5 })

  }

}

回到顶部