ArkUI List 图片拖动排序最佳实践

ArkUI List 拖动排序最佳实践

在 ArkUI 中实现列表拖动排序,主要依赖 List 组件的 onMove 回调。结合 @Local 的响应式更新,几行代码就能实现功能。

数据层

typescript 复制代码
@Local imageUris: Array<string> = [];

渲染层

typescript 复制代码
List() {
  ForEach(this.imageUris, (uri: string, index: number) => {
    ListItem() {
      Stack() {
        Image(uri)
          .width('100%')
          .height(150)
          .objectFit(ImageFit.Cover)
          .borderRadius(10)

        Stack()
          .width('100%')
          .height(150)
      }
    }
    .margin(10)
    .borderRadius(10)
    .backgroundColor('#FFFFFFFF')
  }, (uri: string) => uri)
    .onMove((from: number, to: number) => {
      let tmp = this.imageUris.splice(from, 1);
      this.imageUris.splice(to, 0, tmp[0]);
    })
}

onMove 回调

onMove 是整个拖动排序的核心。当手指长按某个 ListItem 并拖动到新位置时,系统会触发这个回调,并传入两个索引:被拖动项的原位置 from,和目标位置 to

这里的实现利用了数组的 splice 方法两步走:

  1. splice(from, 1) --- 从原位置切出被拖动的元素
  2. splice(to, 0, ...) --- 将其插入到目标位置

由于数组引用没有变化(splice 是 in-place 操作),@Local 的响应式驱动需要依赖 ArkUI 的代理对象机制。在 ForEach 中使用稳定的 key 配合 splice 操作,框架能正确追踪数组变化并触发最小粒度的 UI 更新。

如果需要保留排序结果到持久化存储,比如 UserInfo 或数据库,可以在 onMove 回调末尾追加对应的保存逻辑。

图片选择

配合系统 PhotoViewPicker,最多选 20 张:

typescript 复制代码
async selectImages(): Promise<void> {
  const photoPicker = new photoAccessHelper.PhotoViewPicker();
  const photoSelectOptions = new photoAccessHelper.PhotoSelectOptions();
  photoSelectOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE;
  photoSelectOptions.maxSelectNumber = 20;

  const photoSelectResult = await photoPicker.select(photoSelectOptions);
  if (photoSelectResult?.photoUris?.length > 0) {
    this.imageUris = [...this.imageUris, ...photoSelectResult.photoUris];
  }
}

组件层级

scss 复制代码
List (onMove 接收拖动事件)
├── ListItem (长按触发拖动)
│   └── Stack (布局容器)
│       ├── Image (图片展示)
│       └── Stack (透明覆盖层,透传手势)
└── ListItem ...

注意事项

  • 透明覆盖层 --- 当 ListItem 内只包含 Image 时,Image 组件会优先处理手势,导致 onMove 无法触发。在 Image 上方添加一个透明 Stack 铺满父容器尺寸,将手势透传给 ListItem。Stack 默认裁剪超出内容,圆角设置不受影响。
  • ForEach 需要稳定的 key --- 使用 (uri: string) => uri 作为唯一标识,避免排序时列表项渲染错乱。
相关推荐
大雷神11 小时前
第26篇|单摄预览会话:CameraInput、PreviewOutput、PhotoSession 的关系
harmonyos
不羁的木木19 小时前
Form Kit(卡片开发服务)学习笔记01-核心概念与架构设计
笔记·学习·harmonyos
不羁的木木19 小时前
ArkWeb实战学习笔记01-核心概念与架构设计
笔记·学习·harmonyos
Goway_Hui20 小时前
【鸿蒙原生应用开发--ArkUI--010】Recipe-app 菜谱应用开发教程
华为·harmonyos
●VON20 小时前
鸿蒙 BodyAR 实战:基于人体骨骼追踪的体感运动计数器开发全解
华为·ar·harmonyos·鸿蒙·新特性
Davina_yu20 小时前
页面路由导航:Router与Navigation组件的跳转传参(7)
harmonyos·鸿蒙·鸿蒙系统
Ww.xh21 小时前
鸿蒙WebView IPC防伪造请求方案
华为·harmonyos
大雷神1 天前
第25篇|Surface 预览控制:ArkUI 页面如何接住相机画面
harmonyos
大雷神1 天前
第24篇|相机权限和设备枚举:先判断能力再打开预览
harmonyos
Goway_Hui1 天前
【鸿蒙原生应用开发--ArkUI--003】TodoApp - 待办事项应用教程
华为·harmonyos