鸿蒙Next Grid实现拖动排序踩坑 原创

auhgnixgnahz
发布于 2025-6-12 21:16
浏览
0收藏

案例背景
例如当我们在朋友圈分享图片时,选了9张图片,想调整顺序,这时就会用到拖动排序。
最终效果
鸿蒙Next Grid实现拖动排序踩坑-鸿蒙开发者社区
实现过程
1.通过Picker组件选取照片展示到Grid网格布局中
2.设置编辑模式开启editMode(true),如果想增加动画效果,可以增加设置supportAnimation(true)
3.增加开始拖动和拖动结束的回调,开始时设置拖动过程中的组件样式,结束拖拽回调是做顺序调整
展示
鸿蒙Next Grid实现拖动排序踩坑-鸿蒙开发者社区
发现好像没有效果呢?
因为开启了Gride编辑模式,Image本身是有拖拽功能的,和Grid的GridItem拖拽冲突,因此,要禁用掉Image的拖拽draggable(false)
再演示:
鸿蒙Next Grid实现拖动排序踩坑-鸿蒙开发者社区
禁用掉Image的拖拽是可以改变顺序了,但是为什么没有动画效果呢?官方文档查了半天,感觉也没啥问题呀,开始拖拽和结束拖拽的回调都能收到,为啥就没有拖拽的动画效果呢???
最终找到原因是我的Grid布局设置是自适应排列
.maxCount(9)
.layoutDirection(GridDirection.Row),没有限制子组件比例,这种布局元素本身就是可根据布局大小动态移动的。
然后将列设置成3等分展示columnsTemplate(‘1fr 1fr 1fr’)
展示:
鸿蒙Next Grid实现拖动排序踩坑-鸿蒙开发者社区
看着好像是可以排序也有拖拽效果了,但是释放之后,其他元素的位置没有保持当前的位置,而是恢复到了移动前,只是改变了拖拽元素的位置。
下面源码中给出了两种排序模式:

//网格布局
Grid() {
  ForEach(this.imgs, (item: string) => {
    GridItem() {
      Image(item).objectFit(ImageFit.Cover).width(100).height(100)
        .draggable(false)
    }
  }, (item: string) => item)
}
.width('100%')
.height(Math.ceil(this.imgs.length/3)*110)
.columnsTemplate('1fr 1fr 1fr')
// .maxCount(9)
// .layoutDirection(GridDirection.Row)
.columnsGap(10)
.rowsGap(10)
.padding({ left: 20, right: 20 })
.editMode(true)
.supportAnimation(true)
//第一次拖拽此事件绑定的组件时,触发回调。
.onItemDragStart((event: ItemDragInfo, itemIndex: number) => {
  //设置拖拽过程中显示的图片。
  return this.pixelMapBuilder(this.imgs[itemIndex]);
})
//当在本组件范围内停止拖拽行为时,触发回调。
.onItemDrop((_, itemIndex: number, insertIndex: number,
  isSuccess: boolean) => {
  if (!isSuccess || insertIndex >= this.imgs.length) {
    return;
  }
  this.changeIndex(itemIndex, insertIndex);
})

//拖拽过程样式
@Builder pixelMapBuilder(imgSource:string) {
  Image(imgSource).objectFit(ImageFit.Cover).width(100).height(100)
    .draggable(false)
}

//拖拽之后改变元素位置
changeIndex(index1: number, index2: number) {
  //这种方式可以保存移动过程中的其他元素位置变化
  let tmp = this.imgs.splice(index1, 1);
  this.imgs.splice(index2, 0, tmp[0]);

  //这种方式只能改变拖动元素和释放位置元素的顺序,其他元素还会恢复之前的顺序
  // let temp: string;
  // temp = this.imgs[index1];
  // this.imgs[index1] = this.imgs[index2];
  // this.imgs[index2] = temp;
}

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
分类
已于2025-7-10 09:06:52修改
收藏
回复
举报
回复
    相关推荐