HarmonyOS 鸿蒙Next:List使用ListItemGroup时,ForEach的onMove无法正常工作

发布于 1周前 作者 sinazl 来自 鸿蒙OS

HarmonyOS 鸿蒙Next:List使用ListItemGroup时,ForEach的onMove无法正常工作

List组件在无ListItemGroup时,ForEach的onMove能正常工作,添加ListItemGroup后,无法正常工作。

拖动排序正常代码:

List() {
    ForEach(this.minuteAttached, (item: TechIndexModelWrapper) => {
      ListItem() {
        this.cellBuilder(item)
      }
      .width(""100% "")
      .height(this.cellHeight)
    }, (item: TechIndexModelWrapper, index: number) => item.settingName + index.toString())
      .onMove((from: number, to: number) => {
        let tmp = this.minuteAttached.splice(from, 1);
        this.minuteAttached.splice(to, 0, tmp[0])
      })
  }
  .draggable(true)

添加表头ListItemGroup后无法拖动编辑:

List() {
    ListItemGroup({ header: this.headerTitleBuilder("分时指标设置") }) {
      ForEach(this.minuteAttached, (item: TechIndexModelWrapper) => {
        ListItem() {
          this.cellBuilder(item)
        }
        .width(""100% "")
        .height(this.cellHeight)
      }, (item: TechIndexModelWrapper, index: number) => item.settingName + index.toString())
        .onMove((from: number, to: number) => {
          let tmp = this.minuteAttached.splice(from, 1);
          this.minuteAttached.splice(to, 0, tmp[0])
        })
    }
  }
  .draggable(true)

请问如何使带有ListItemGroup的List实现正常拖动。


更多关于HarmonyOS 鸿蒙Next:List使用ListItemGroup时,ForEach的onMove无法正常工作的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html

3 回复

经过测试在ListItemGroup中,ForEach的onMove确实不能正常工作。你可以参考以下代码,使用nestedScroll属性实现了内层List组件和外层Scroll组件的嵌套滚动,也可以实现菜单滑动吸顶效果。

//xxx.ets
@Entry
@Component
struct StickyNestedScroll {
    @State arr: number[] = []
    @Styles
    listCard() {
        .backgroundColor(Color.White)
        .height(72)
        .width("100%")
        .borderRadius(12)
    }
    build() {
        Scroll() {
            Column() {
                Text("Scroll Area")
                    .width("100%")
                    .height("40%")
                    .backgroundColor('#0080DC')
                    .textAlign(TextAlign.Center)
                Tabs({ barPosition: BarPosition.Start }) {
                    TabContent() {
                        List({ space: 10 }) {
                            ForEach(this.arr, (item: number) => {
                                ListItem() {
                                    Text("" + item)
                                        .fontSize(16)
                                }.listCard()
                            }, (item: string) => item)
                                .onMove((from: number, to: number) => {
                                    let tmp = this.arr.splice(from, 1);
                                    this.arr.splice(to, 0, tmp[0])
                                })
                        }.width("100%")
                            .edgeEffect(EdgeEffect.Spring)
                            .nestedScroll({
                                scrollForward: NestedScrollMode.PARENT_FIRST,
                                scrollBackward: NestedScrollMode.SELF_FIRST
                            })
                    }.tabBar("Tab1")
                    TabContent() {
                    }.tabBar("Tab2")
                }
        .vertical(false)
                    .height("100%")
            } .width("100%")
        }
    .edgeEffect(EdgeEffect.Spring)
            .friction(0.6)
            .backgroundColor('#DCDCDC')
            .scrollBar(BarState.Off)
            .width('100%')
            .height('100%')
    }
    aboutToAppear() {
        for (let i = 0; i < 30; i++) {
            this.arr.push(i)
        }
    }
}

import curves from '@ohos.curves';
import Curves from '@ohos.curves'
// xxx.ets
@Entry
@Component
struct Page6272 {
    @State private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    @State dragItem: number = -1
    @State scaleItem: number = -1
    @State neighborItem: number = -1
    @State neighborScale: number = -1
    private dragRefOffset: number = 0
    @State offsetX: number = 0
    @State offsetY: number = 0
    private ITEM_INTV: number = 120
    scaleSelect(item: number): number {
        if (this.scaleItem == item) {
            return 1.05
        } else if (this.neighborItem == item) {
            return this.neighborScale
        } else {
            return 1
        }
    }
    itemMove(index: number, newIndex: number): void {
        let tmp = this.arr.splice(index, 1)
        this.arr.splice(newIndex, 0, tmp[0])
    }
    @Builder
    private headerTitleBuilder(title: string) {
        Column() {
            Row() {
                Text(title)
                    .width(200)
                    .height(26)
                    .margin({ left: 15 })
                    .fontSize('18vp')
                    .textAlign(TextAlign.Start)
                    .fontColor(Color.Blue)
            }
                .height(46)
                .width('100%')
        }
            .height(56)
            .width('100%')
            .backgroundColor(Color.White)
    }
    build() {
        Stack() {
            List({ space: 20, initialIndex: 0 }) {
                ListItemGroup({ header: this.headerTitleBuilder("分时指标设置"), space: 10 }){
                    ForEach(this.arr, (item: number) => {
                        ListItem() {
                            Text('' + item)
                                .width('100%')
                                .height(100)
                                .fontSize(16)
                                .textAlign(TextAlign.Center)
                                .backgroundColor(0xFFFFFF)
                                .shadow(this.scaleItem == item ? { radius: 70, color: '#15000000', offsetX: 0, offsetY: 0 } :
                                    { radius: 0, color: '#15000000', offsetX: 0, offsetY: 0 })
                                .animation({ curve: Curve.Sharp, duration: 300 })
                        }
                            .scale({ x: this.scaleSelect(item), y: this.scaleSelect(item) })
                            .zIndex(this.dragItem == item ? 1 : 0)
                            .translate(this.dragItem == item ? { y: this.offsetY } : { y: 0 })
                            .gesture(
                                // 以下组合手势为顺序识别,当长按手势事件未正常触发时则不会触发拖动手势事件
                                GestureGroup(GestureMode.Sequence,
                                    LongPressGesture({ repeat: true })
                                        .onAction((event?: GestureEvent) => {
                                            animateTo({ curve: Curve.Friction, duration: 300 }, () => {
                                                this.scaleItem = item
                                            })
                                        })
                                        .onActionEnd(() => {
                                            animateTo({ curve: Curve.Friction, duration: 300 }, () => {
                                                this.scaleItem = -1
                                            })
                                        }),
                                    PanGesture({ fingers: 1, direction: null, distance: 0 })
                                        .onActionStart(() => {
                                            this.dragItem = item
                                            this.dragRefOffset = 0
                                        })
                                        .onActionUpdate((event: GestureEvent) => {
                                            this.offsetY = event.offsetY - this.dragRefOffset
                                            this.neighborItem = -1
                                            let index = this.arr.indexOf(item)
                                            let curveValue = Curves.initCurve(Curve.Sharp)
                                            let value: number = 0
                                            //根据位移计算相邻项的缩放
                                            if (this.offsetY < 0) {
                                                value = curveValue.interpolate(-this.offsetY / this.ITEM_INTV)
                                                this.neighborItem = this.arr[index - 1]
                                                this.neighborScale = 1 - value / 20;
                                                console.log('neighborScale:' + this.neighborScale.toString())
                                            } else if (this.offsetY > 0) {
                                                value = curveValue.interpolate(this.offsetY / this.ITEM_INTV)
                                                this.neighborItem = this.arr[index + 1]
                                                this.neighborScale = 1 - value / 20;
                                            }
                                            //根据位移交换排序
                                            if (this.offsetY > this.ITEM_INTV / 2) {
                                                animateTo({ curve: curves.interpolatingSpring(0, 1, 400, 38) }, () => {
                                                    this.offsetY -= this.ITEM_INTV
                                                    this.dragRefOffset += this.ITEM_INTV
                                                    this.itemMove(index, index + 1)
                                                })
                                            } else if (this.offsetY < -this.ITEM_INTV / 2) {
                                                animateTo({ curve: curves.interpolatingSpring(0, 1, 400, 38) }, () => {
                                                    this.offsetY += this.ITEM_INTV
                                                    this.dragRefOffset -= this.ITEM_INTV
                                                    this.itemMove(index, index - 1)
                                                })
                                            }
                                        })
                                        .onActionEnd((event: GestureEvent) => {
                                            animateTo({ curve: curves.interpolatingSpring(0, 1, 400, 38) }, () => {
                                                this.dragItem = -1
                                                this.neighborItem = -1
                                            })
                                            animateTo({
                                                curve: curves.interpolatingSpring(14, 1, 170, 17), delay: 150
                                            }, () => {
                                                this.scaleItem = -1
                                            })
                                        })
                                )
                                    .onCancel(() => {
                                        animateTo({ curve: curves.interpolatingSpring(0, 1, 400, 38) }, () => {
                                            this.dragItem = -1
                                            this.neighborItem = -1
                                        })
                                        animateTo({
                                            curve: curves.interpolatingSpring(14, 1, 170, 17), delay: 150
                                        }, () => {
                                            this.scaleItem = -1
                                        })
                                    })
                            )
                    }, (item: number) => item.toString())
                }.divider({ strokeWidth: 1, color: Color.Black })
            }.sticky(StickyStyle.Header)
        }.width('100%').height('100%').backgroundColor(0xDCDCDC).padding({ top: 5 })
    }
}

更多关于HarmonyOS 鸿蒙Next:List使用ListItemGroup时,ForEach的onMove无法正常工作的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


为啥我把数组换成对象数组后,交换位置就没有动画效果了?

在HarmonyOS鸿蒙Next系统中,使用ListItemGroup时,如果遇到ForEachonMove无法正常工作的问题,可能是由于以下几个原因:

  1. 数据绑定问题:确保ListItemGroup中的数据源正确绑定,并且数据源支持移动操作。检查数据源是否实现了必要的接口或方法,以支持列表项的移动。

  2. 事件处理:onMove事件的处理逻辑可能存在问题。确认在ForEach组件中正确设置了onMove回调,并且回调逻辑能够正确执行移动操作。

  3. UI刷新:在移动项后,确保UI能够正确刷新以反映数据的变化。可能需要手动触发UI刷新,或者在数据变化时通知UI组件进行更新。

  4. 组件属性:检查ListItemGroupForEach组件的属性设置,确保没有属性导致移动操作被禁止或忽略。

  5. 版本兼容性:确认你使用的HarmonyOS鸿蒙Next版本是否支持当前使用的ListItemGroupForEach组件的特性。有时,系统更新可能引入新的行为或修复旧的问题。

如果以上检查均未能解决问题,可能是系统或组件内部的bug。此时,建议联系官方客服获取进一步的支持。如果问题依旧没法解决请联系官网客服,官网地址是 https://www.itying.com/category-93-b0.html

回到顶部