HarmonyOS 鸿蒙Next中列表拖拽排序拖到屏幕边缘后页面不会滚动

HarmonyOS 鸿蒙Next中列表拖拽排序拖到屏幕边缘后页面不会滚动 在列表很长的情况下拖动排序,列表项拖动到屏幕底部边缘的时候页面不会自动滑动,需要释放拖拽项然后滚动页面在进行拖,需要二次操作。应该系统层面就要支持这种默认行为,就像双击状态栏页面回到顶部这种默认行为也已经支持了,希望官方支持一下。

官方拖拽排序文档:https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-universal-attributes-drag-sorting#%E7%A4%BA%E4%BE%8B1%E4%BD%BF%E7%94%A8onmove%E8%BF%9B%E8%A1%8C%E6%8B%96%E6%8B%BD


更多关于HarmonyOS 鸿蒙Next中列表拖拽排序拖到屏幕边缘后页面不会滚动的实战教程也可以访问 https://www.itying.com/category-93-b0.html

21 回复

尊敬的开发者,您好,auto是自适应子组件,相当于list全展开了,onMove就不会拖拽滚动了。

更多关于HarmonyOS 鸿蒙Next中列表拖拽排序拖到屏幕边缘后页面不会滚动的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


目前官方拖拽排序示例主要提供的是拖拽排序事件处理,例如通过 onMove 更新数据源;我没有在公开文档里看到“拖到滚动容器边缘自动滚动”的内置开关。

如果现在要实现这个交互,建议在应用层做边缘滚动:拖拽过程中判断手指位置是否进入列表顶部或底部阈值,进入后通过绑定的 Scroller 调用 scrollTo 或滚动偏移方法定时滚动,离开阈值后停止;排序本身仍由 onMove 更新数据源。若期望系统直接支持,可以作为 ArkUI 能力建议提交。

依据:Scroll/Scroller 官方文档:

https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-container-scroll

开发者你好,当前你说的这种现象,在API23+的设备上,都是符合你这边的预期的(列表项拖动到屏幕底部边缘的时候页面可以自动滑动)。你这边可以升级DevEco Studio版本到6.1,然后下载对应版本的模拟器进行测试。

升级了还是不行哦,我的List高度设置的是auto自然高度,滚动是页面根节点Scroll的滚动。你说的符合预期可能是List本身独占整个面面才行

开发者你好,当前的情况下,只要给List设置固定高度,就可以符合预期;List不需要独占整个页面,比如设置50%。

你这边的业务场景,是必须给List设置auto自然高度吗。是否方便描述一下具体场景。

List本身不需要局部滚动,跟随整个页面一起滚动的,

两个示例都可以正常拖拽(项加到1000了),6.0的手机跑的。

你好,没有复现到你说的这个问题。开发环境: DevEco Studio 6.1.0 Release, API 23。

或者在6.0以上就已修复该问题,建议更新版本试试。

cke_1147.gif

// xxx.ets
@Entry
@Component
struct ListOnMoveExample {
  @State arr: number[] = Array.from({ length: 100 }, (_: number, i: number) => i)

  build() {
    Column() {
      List({ space: 20, initialIndex: 0 }) {
        ForEach(this.arr, (item: number) => {
          ListItem() {
            Text('第一个List' + item)
              .width('100%')
              .height(80)
              .fontSize(16)
              .textAlign(TextAlign.Center)
              .borderRadius(10)
              .backgroundColor(0xFFFFFF)
          }
        }, (item: string) => item)
          .onMove((from: number, to: number) => {
            let tmp = this.arr.splice(from, 1);
            this.arr.splice(to, 0, tmp[0]);
            console.info('List onMove From: ' + from);
            console.info('List onMove To: ' + to);
          })
      }.width('90%')
      .scrollBar(BarState.Off)
    }.width('100%').height('100%').backgroundColor(0xDCDCDC).padding({ top: 5 })
  }
}

我的IDE是6.0.2,可能需要更高版本

你可以先升级试下,后续有任何问题欢迎您随时提问~

有要学HarmonyOS AI的同学吗,联系我:https://www.itying.com/goods-1206.html,

升级了也没用,我们的区别在于你的页面滚动就是List的滚动,而我的List只是局部本身自然高度,页面滚动页面根节点的滚动

这个问题本质上是:

HarmonyOS 当前 List 的 onMove / 拖拽排序,
系统并没有内置“拖到边缘自动滚动”的能力。

也就是说:

拖拽状态下,
ListScroller 不会像 Android RecyclerView、
iOS UITableView 那样自动边缘滚动。

所以你现在看到的现象:

拖到屏幕底部 → 页面不滚
必须松手 → 手动滚动 → 再继续拖

其实是目前框架行为,不是你代码问题。

目前官方示例:

onMove
onItemDragMove

都没有实现自动滚动。

现在业内常见做法是:

开发者自己监听拖拽位置,
靠近顶部/底部时,
手动调用 ListScroller.scrollBy()

例如思路:

.onItemDragMove((event, itemIndex, insertIndex) => {

  // 靠近底部
  if (event.y > this.screenHeight - 120) {
    this.scroller.scrollBy(0, 20)
  }

  // 靠近顶部
  if (event.y < 120) {
    this.scroller.scrollBy(0, -20)
  }
})

配合:

List({ scroller: this.scroller })

实现“伪自动滚动”。

不过这个方案体验一般,还会遇到:

  • 滚动速度不平滑
  • 高频 drag move 卡顿
  • 边界抖动
  • insertIndex 错乱
  • LazyForEach 刷新跳动

所以很多人也在提建议:

希望官方把“边缘自动滚动”
做成 List.onMove 的系统默认行为。

因为这是:

移动端拖拽排序的行业标准交互

像:

  • iOS
  • Android
  • Flutter ReorderableListView
  • RecyclerView ItemTouchHelper

其实都已经内建支持。

你这个建议是合理的,而且确实属于:

框架层缺失能力

不是业务代码问题。

另外补充一点:

如果你现在要自己实现,

建议:

不要用 ForEach
尽量用 LazyForEach

否则长列表拖拽时整个 List 重建,

会导致滚动位置丢失。

哥们,你的回答有股ai味儿

确实还没有支持这个操作。目前官方的拖拽排序能力主要聚焦于数据顺序的交换逻辑,这种内置边缘自动滚动的行为,你得自己考虑实现了。实在业务有需要,我可以给你个实现思路,先获取当前拖拽项的坐标,判断是否接近屏幕边缘,当检测到边缘条件时,调用滚动容器的滚动接口(如 Scroll 组件的 scrollToscrollEdge 方法),以一定速度自动滚动页面。需注意滚动时应保持拖拽项的相对位置

知道实现思路的,还是希望官方支持

哈哈,这个得看官方是否有意愿做了

可以通过监听拖拽手势的坐标位置,判断拖拽项是否触及屏幕顶部 / 底部可视边缘;触发列表scrollTo/ 滚动偏移逻辑,实现边拖拽边自动滚动

这个应该属于业务范畴了;官方给的api不会完全覆盖所有场景

我知道怎么处理。。。这不属于业务范畴,这种算系统层面的一种优化,没有不影响,有就属于锦上添花,就像页面有滚动的情况下双击状态栏回到顶部是一个道理,之前也没有需要自己处理,现在系统层面也支持了

提个工单看看呗,看会不会优化,有了更好,方便开发

在鸿蒙Next中,列表拖拽到边缘时页面不滚动,通常是因为未启用拖拽时的自动滚动机制。需检查List组件的edgeEffect属性是否设为EdgeEffect.Scroll,并确保listItemDragEnabled已开启。可监听拖拽事件,在onItemDragStart中记录拖拽状态,在onItemDragMove中判断拖拽位置是否接近列表边界,手动调用scrollToscrollBy实现滚动。同时确认列表容器的layoutBound未限制滚动区域。

回到顶部