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。可以实现预期效果。
【解决方案】
根据以上分析的思路,解决方案如下:
- 根据元素不一样,来设置不同的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)
}
}
- 拖拽图片后,根据拖拽的位置序号来进行重新排序。
.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])
}
- 拖拽过程中显示自定义组件。
@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
事件冲突。解决方案如下:
- 使用
hitTestBehavior
API,将“+”图片设置为HitTestMode.Default
,添加的图片设置为HitTestMode.None
。 - 在
onItemDrop
事件中,根据拖拽位置重新排序图片。 - 在
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)
}