HarmonyOS鸿蒙Next中Grid组件编辑模式打开后,仍然不可以拖动组件该如何解决

HarmonyOS鸿蒙Next中Grid组件编辑模式打开后,仍然不可以拖动组件该如何解决

【问题现象】

想要在一个Grid组件里面实现以下效果:

预期效果:预加载的“+”图片用来添加图片到Grid组件,该图片不能被移动,添加进来的图片可以被移动。

实际效果:editMode处于打开状态时,元素依然不能被拖动。

问题代码如下:

Grid(this.scroller)
  ForEach(this.selectMedias, (item: string, index: number) => {
    GridItem() {
      Stack() {
        this.itemGrid(item, index)
      }
      .padding({ bottom: 15 })
    }
  }, (item: string, index: number) => {
    return `${item}_${index}`
  })
}
.editMode(true)

【背景知识】

【定位思路】

  • editMode是Grid组件的API,控制整个Grid组件是否能编辑。这里出现editMode打开了依然无法拖动,是因为拖动事件跟onClick事件发送了冲突。
  • 想要解决问题,需要用到API hitTestBehavior。把“+”图片设置为HitTestMode.Default,被添加进来的图片设置为HitTestMode.None。可以实现预期效果。

【解决方案】

根据以上分析的思路,解决方案如下:

  1. 根据元素不一样,来设置不同的HitTestMode。
// Grid默认的首个与元素是-1
@State selectMedias: Array<string> = ["-1"] 
@Builder
itemGrid(item: string, index: number) {
  // -1元素即是+号图片只需要加上onclick事件,无需其他特殊处理,HitTestMode的默认值就是Default
  if (item === "-1") {
    Image($r('app.media.newsinformantspage_item_imagepicker_default'))
      .objectFit(ImageFit.Cover)
      // onclick事件,添加图片到Grid
      .onClick(() => {
        this.selectImages({
          MIMEType: photoAccessHelper.PhotoViewMIMETypes.IMAGE_VIDEO_TYPE,
          maxSelectNumber: this.maxSelectPics - (this.selectMedias.length - 1)
        }, (photoSelectResult: photoAccessHelper.PhotoSelectResult) => {
          this.selectMedias = this.selectMedias.concat(photoSelectResult.photoUris)
          console.log('selectMedias', this.selectMedias.toString());
          if (this.selectMedias.length > this.maxSelectPics) {
            this.selectMedias = this.selectMedias.filter(data => data !== "-1");
          }
        })
      })
  } else {
    // 通过onclick事件添加进来的图片,设置hitTestBehavior 为HitTestMode.None
    Image(item)
      .hitTestBehavior(HitTestMode.None)
  }
}
  1. 拖拽图片后,根据拖拽的位置序号来进行重新排序。
.onItemDragStart((event:
  if (this.selectMedias[itemIndex] !== "-1") {
    // 在onItemDragStart函数返回自定义组件,可在拖拽过程中显示此自定义组件。
    return this.itemDragGrid(this.selectMedias[itemIndex], itemIndex)
  }
})
.onItemDrop((event: ItemDragInfo, itemIndex: number, insertIndex: number, isSuccess: boolean) => {
  // 执行gridItem切换操作
  if (isSuccess && insertIndex < this.selectMedias.length) {
    // 点击选择图标不进行交换
    if (this.selectMedias[itemIndex] === "-1") {
      return
    }
    // 修改图片的index达到重新排序的效果
    this.changeIndex(itemIndex, insertIndex)
  }
})

/**
 * 交换应用位置函数
 * @param itemIndex 目标网格元素的index
 * @param insertIndex 被切换网格元素的index
 */
changeIndex(itemIndex: number, insertIndex: number): void {
  this.selectMedias.splice(insertIndex, 0, this.selectMedias.splice(itemIndex, 1)[0])
}
  1. 拖拽过程中显示自定义组件。
@Builder
// 根据当前被拖拽的Item,封装定义组件
itemDragGrid(item: string, index: number) {
  Image(item)
    .objectFit(ImageFit.Cover)
    .width(this.imageWH)
    .height(this.imageWH)
    .borderRadius(4)
}

效果图如下:

点击放大


更多关于HarmonyOS鸿蒙Next中Grid组件编辑模式打开后,仍然不可以拖动组件该如何解决的实战教程也可以访问 https://www.itying.com/category-93-b0.html

1 回复

更多关于HarmonyOS鸿蒙Next中Grid组件编辑模式打开后,仍然不可以拖动组件该如何解决的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS鸿蒙Next中,Grid组件编辑模式打开后仍无法拖动组件

在HarmonyOS鸿蒙Next中,Grid组件编辑模式打开后仍无法拖动组件,原因是拖动事件与onClick事件冲突。解决方案如下:

  1. 使用hitTestBehavior API,将“+”图片设置为HitTestMode.Default,添加的图片设置为HitTestMode.None
  2. onItemDrop事件中,根据拖拽位置重新排序图片。
  3. onItemDragStart事件中,显示自定义拖拽组件。

具体代码实现

@State selectMedias: Array<string> = ["-1"]

@Builder
itemGrid(item: string, index: number) {
  if (item === "-1") {
    Image($r('app.media.newsinformantspage_item_imagepicker_default'))
      .onClick(() => {
        this.selectImages({
          MIMEType: photoAccessHelper.PhotoViewMIMETypes.IMAGE_VIDEO_TYPE,
          maxSelectNumber: this.maxSelectPics - (this.selectMedias.length - 1)
        }, (photoSelectResult: photoAccessHelper.PhotoSelectResult) => {
          this.selectMedias = this.selectMedias.concat(photoSelectResult.photoUris)
        })
      })
  } else {
    Image(item)
      .hitTestBehavior(HitTestMode.None)
  }
}

.onItemDragStart((event: ItemDragInfo, itemIndex: number) => {
  if (this.selectMedias[itemIndex] !== "-1") {
    return this.itemDragGrid(this.selectMedias[itemIndex], itemIndex)
  }
})
.onItemDrop((event: ItemDragInfo, itemIndex: number, insertIndex: number, isSuccess: boolean) => {
  if (isSuccess && insertIndex < this.selectMedias.length) {
    this.changeIndex(itemIndex, insertIndex)
  }
})

changeIndex(itemIndex: number, insertIndex: number): void {
  this.selectMedias.splice(insertIndex, 0, this.selectMedias.splice(itemIndex, 1)[0])
}

@Builder
itemDragGrid(item: string, index: number) {
  Image(item)
    .objectFit(ImageFit.Cover)
    .width(this.imageWH)
    .height(this.imageWH)
    .borderRadius(4)
}
回到顶部