加入下方官方CSDN班级,得鸿蒙礼盒

一起拿鸿蒙礼盒,戳我戳我!!

本期活动时间:2025年8月1日-12月31日

如有问题欢迎私聊我呀!


问题现象

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

  1. 原始元素排列:

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

效果预览

拖拽元素后能够自动滚屏:

背景知识

  • onItemDragMove:拖拽在网格元素范围内移动时触发。
  • onScrollIndex:Grid显示区域上第一个子组件或最后一个组件的索引值有变化就会触发。
  • Curves.interpolatingSpring:构造插值器弹簧曲线对象,生成一条从0到1的动画曲线,实际动画值根据曲线进行插值计算。

问题定位

  1. 由于当前Grid不支持拖拽自动滚屏效果,所以考虑先捕捉拖拽动作,然后进行滚屏处理。
    • 使用API onItemDragMove捕捉到拖拽动作。
    • 使用API onScrollIndex定位当前页面的起始和终止元素的index。
  1. 通过item被拖拽的目标位置来判断是上滑还是下滑。
    • 如果被拖动移动超过2个index,最终的目标位置还是在上栏 ,就往上滑。
    • 如果被拖动的目标位置在下图的下栏 ,就往下滑。

分析结论

由于当前Grid不支持拖拽自动滚屏效果,所以考虑先捕捉拖拽动作,然后进行滚屏处理:可以通过item被拖拽的目标位置来判断是上滑还是下滑。

修改建议

  1. 记录下滑动时的起始位置和终点位置。
  2. 元素移动,通过移动位置来判断是上滑还是下滑。
  3. 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 })

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐