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 作为唯一标识,避免排序时列表项渲染错乱。
相关推荐
HwJack206 小时前
HarmonyOS APP开发玩转鸿蒙 HSP:打造高复用“乐高模块”的底层逻辑
华为·harmonyos
●VON13 小时前
28个Token重构鸿蒙App:企业级设计系统的搭建实践
华为·重构·harmonyos
求学中--14 小时前
AppStorage和LocalStorage有什么区别?鸿蒙全局状态管理方案选型指南
华为·harmonyos
求学中--17 小时前
鸿蒙状态管理一文通:@State/@Prop/@Link/@Provide四大装饰器,15分钟彻底搞懂
华为·harmonyos
nashane18 小时前
HarmonyOS 6学习:HWAsan监测开启后应用崩溃的终极解决方案
学习·华为·harmonyos·harmonyos 5
Exploring18 小时前
实测 Vibe Coding:快速开发 HarmonyOS 玩 Android 客户端
harmonyos
UnicornDev18 小时前
【Flutter x HarmonyOS 6】魔方计时APP——记录页面的UI设计
flutter·ui·华为·harmonyos·鸿蒙
Swift社区19 小时前
鸿蒙 PC + 手机 + 平板:一次真正的多端应用实战
智能手机·电脑·harmonyos
纤纡.19 小时前
HarmonyOS 鸿蒙 ArkTS 实战:从零开发生肖集卡抽奖小程序
华为·小程序·harmonyos·deveco studio
枫叶丹420 小时前
【HarmonyOS 6.0】Data Augmentation Kit端侧问答模型:本地化智能问答的技术演进
开发语言·华为·harmonyos