HarmonyOS鸿蒙Next中如何解决Grid组件拖拽到边缘时无法继续拖动的问题

HarmonyOS鸿蒙Next中如何解决Grid组件拖拽到边缘时无法继续拖动的问题

【问题现象】

将Grid里的元素拖拽到边缘位置时,无法继续拖动。如下图:

(1)原始元素排列:

点击放大

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

点击放大

【背景知识】

【定位思路】

(1)由于当前Grid不支持拖拽自动滚屏效果,所以考虑先捕捉拖拽动作,然后进行滚屏处理:

  • 使用API onItemDragMove捕捉到拖拽动作。
  • 使用API onScrollIndex定位当前页面的起始和终止元素的index。

(2)通过item被拖拽的目标位置来判断是上滑还是下滑:

  • 如果被拖动移动超过2个index,最终的目标位置还是在上栏,就往上滑。
  • 如果被拖动的目标位置在下图的下栏,就往下滑。如下图所示:

点击放大

【解决方案】

(1)记录下滑动时的起始位置和终点位置。

代码示例如下:

// 滚轴滑动,记录下滑动时的起始位置和终点位置
.onScrollIndex((start: number, end: number) => {
     this.startIndex = start
     this.endIndex = end
})

(2)元素移动,通过移动位置来判断是上滑还是下滑。

代码示例如下:

.onItemDragMove((event: ItemDragInfo, itemIndex: number, insertIndex: number) => {
  // 创建一个阶梯曲线,详情见上方的官方文档
  let curve = Curves.interpolatingSpring(10, 1, 228, 30)
  // 计算当前Y轴的位移量
  let yOffset: number = this.scroller.currentOffset().yOffset;
  // 上移 因为insertIndex 始终为整数,所以,这里判断,当拖拽插入位置小于起始当前页的item第二行首页元素的index,并且位移超过2时,判断为上移
  if (insertIndex <= this.startIndex + 2 && insertIndex > 2) {
    yOffset = yOffset - 55;
  }
  // 下移 当拖拽插入位置大于起始当前页的item第二行首页元素的index,判断为下移
  if (insertIndex >= this.endIndex - 2 && insertIndex < this.numbers.length - 1) {
    yOffset = yOffset + 55;
  }
  console.log('yOffset = ' + yOffset)
  // x轴保持不变,根据计算从用户来的y值和设置好的阶梯曲线实现scroller的滑动
  this.scroller.scrollTo({ xOffset: 0, yOffset: yOffset, animation: { duration: 1000, curve: curve } })
})

(3)GridItem拖动结束,修改item的序号。

代码示例如下:

// GridItem拖动结束
.onItemDrop((
  isSuccess: boolean) => { // 绑定此事件的组件可作为拖拽释放目标,当在本组件范围内停止拖拽行为时,触发回调。
  // isSuccess=false时,说明drop的位置在grid外部;insertIndex > length时,说明有新增元素的事件发生
  if (!isSuccess || insertIndex >= this.numbers.length) {
    return
  }
  console.info('index ' + itemIndex + ', ' + insertIndex) //itemIndex拖拽起始位置,insertIndex拖拽插入位置
  this.changeIndex(itemIndex, insertIndex)
})

问题解决效果如下图,拖拽元素后能够自动滚屏:

点击放大


更多关于HarmonyOS鸿蒙Next中如何解决Grid组件拖拽到边缘时无法继续拖动的问题的实战教程也可以访问 https://www.itying.com/category-93-b0.html

1 回复

更多关于HarmonyOS鸿蒙Next中如何解决Grid组件拖拽到边缘时无法继续拖动的问题的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


使用onItemDragMove捕捉拖拽动作,通过onScrollIndex定位当前页面的起始和终止元素的index。根据拖拽目标位置判断上滑或下滑,使用Curves.interpolatingSpring生成动画曲线,实现自动滚屏。

回到顶部