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 作为唯一标识,避免排序时列表项渲染错乱。
相关推荐
爸爸6194 分钟前
鸿蒙实战:@State 本地状态与 UI 刷新
ui·华为·harmonyos·鸿蒙系统
念雨思19 分钟前
每日穿搭助手:鸿蒙AI应用开发实战——AI衣橱,每日穿搭不再愁
人工智能·华为·powerpoint·harmonyos·鸿蒙
l1340620823524 分钟前
鸿蒙实战:从 rawfile 加载 AI 模型资源
人工智能·华为·harmonyos
心中有国也有家1 小时前
AtomGit Flutter 鸿蒙客户端:Flutter 鸿蒙应用的错误处理与优雅降级策略
学习·flutter·华为·harmonyos
xianjixiance_1 小时前
鸿蒙实战:UnclassifiedArchivePage 长按多选与批量归档
华为·harmonyos·鸿蒙系统
不才难以繁此生1 小时前
ArkUI 筛选状态实战:中式美食列表页怎么让关键词、分类和排序不互相打架
harmonyos·arkts·状态管理·arkui·中式美食
●VON1 小时前
HarmonyKit | 鸿蒙开发:hvigor 构建系统命令行与缓存机制详解
缓存·华为·交互·harmonyos·鸿蒙
星释1 小时前
鸿蒙智能体开发实战:35.鸿蒙壁纸大师 - 调用火山引擎模型生成壁纸
算法·华为·ai·harmonyos·鸿蒙·火山引擎
ZZZMMM.zip1 小时前
思维安检门-逻辑漏洞分析的HarmonyOS开发实践
人工智能·华为·harmonyos·鸿蒙·鸿蒙系统
爸爸6192 小时前
鸿蒙实战:手写板 WritePage 触摸绘图实现
华为·harmonyos·鸿蒙系统