HarmonyOS5 便捷生活类——如何解决Grid组件拖拽到边缘时无法继续拖动的问题
来来来,加入CSDN班级并考证,拿鸿蒙礼盒!
·
加入下方官方CSDN班级,得鸿蒙礼盒
本期活动时间:2025年8月1日-12月31日
如有问题欢迎私聊我呀!
问题现象
将Grid里的元素拖拽到边缘位置时,无法继续拖动。
- 原始元素排列:

- 拖拽元素至边缘位置时,无法继续拖动:

效果预览
拖拽元素后能够自动滚屏:

背景知识
- onItemDragMove:拖拽在网格元素范围内移动时触发。
- onScrollIndex:Grid显示区域上第一个子组件或最后一个组件的索引值有变化就会触发。
- Curves.interpolatingSpring:构造插值器弹簧曲线对象,生成一条从0到1的动画曲线,实际动画值根据曲线进行插值计算。
问题定位
- 由于当前Grid不支持拖拽自动滚屏效果,所以考虑先捕捉拖拽动作,然后进行滚屏处理。
- 使用API onItemDragMove捕捉到拖拽动作。
- 使用API onScrollIndex定位当前页面的起始和终止元素的index。
- 通过item被拖拽的目标位置来判断是上滑还是下滑。
- 如果被拖动移动超过2个index,最终的目标位置还是在上栏 ,就往上滑。
- 如果被拖动的目标位置在下图的下栏 ,就往下滑。

分析结论
由于当前Grid不支持拖拽自动滚屏效果,所以考虑先捕捉拖拽动作,然后进行滚屏处理:可以通过item被拖拽的目标位置来判断是上滑还是下滑。
修改建议
- 记录下滑动时的起始位置和终点位置。
- 元素移动,通过移动位置来判断是上滑还是下滑。
- GridItem拖动结束,修改item的序号。
Column({ space: 5 }) { Grid(this.scroller) { ForEach(this.numbers, (day: string) => { GridItem() { Text(day) .fontSize(16) .backgroundColor(0xF9CF93) .width(80) .height(80) .textAlign(TextAlign.Center) } }) } .columnsTemplate('1fr 1fr 1fr') .columnsGap(10) .rowsGap(10) .width('90%') .backgroundColor(0xFAEEE0) .height('35%') // 设置Grid是否进入编辑模式,进入编辑模式可以拖拽Grid组件内部GridItem .editMode(true) .onScrollIndex((start: number, end: number) => { this.startIndex = start this.endIndex = end }) // 第一次拖拽此事件绑定的组件时,触发回调 .onItemDragStart((event: ItemDragInfo, itemIndex: number) => { this.text = this.numbers[itemIndex] this.currentIndex = itemIndex // 设置拖拽过程中显示的图片 return this.pixelMapBuilder() }) .onItemDrop((event: ItemDragInfo, itemIndex: number, insertIndex: number, // 绑定此事件的组件可作为拖拽释放目标,当在本组件范围内停止拖拽行为时,触发回调 isSuccess: boolean) => { // isSuccess=false时,说明drop的位置在grid外部;insertIndex > length时,说明有新增元素的事件发生 if (!isSuccess || insertIndex >= this.numbers.length) { return } let temp: string; temp = this.numbers[itemIndex]; this.numbers[itemIndex] = this.numbers[insertIndex]; this.numbers[insertIndex] = temp; }) .onItemDragMove((event: ItemDragInfo, itemIndex: number, insertIndex: number) => { // 创建一个阶梯曲线 let curve = Curves.interpolatingSpring(10, 1, 228, 30) // 计算当前Y轴的位移量 let yOffset: number = this.scroller.currentOffset().yOffset; // 上移insertIndex <= this.startIndex+2表示要往上移动,insertIndex>2表示位移量大于2,每行有3个元素,位移量大于2的时候,y轴需要上移 if (insertIndex <= this.startIndex + 2 && insertIndex > 2) { yOffset = yOffset - 55; } // 下移insertIndex >= this.endIndex-2表示在往下移,insertIndex< this.numbers.length-1 if (insertIndex >= this.endIndex - 2) { yOffset = yOffset + 55; } this.scroller.scrollTo({ xOffset: 0, yOffset: yOffset, animation: { duration: 1000, curve: curve } }) }) }.width('100%').margin({ top: 5 })
更多推荐




所有评论(0)