HarmonyOS鸿蒙Next中arkui的list组件的ListItemGroup分组中内容切换后如何置顶

HarmonyOS鸿蒙Next中arkui的list组件的ListItemGroup分组中内容切换后如何置顶

itemHead2() 是一个点击切换的title,处于界面滚动到一定距离后保持吸顶状态,点击不同的text下边的shopIndexGoodsList组件展示不同的商品列表,因为商品列表是可以滑动的,当我在title==1的时候滑动到一定距离后,切换的title==2,shopIndexGoodsList的位置还是在之前title==1时滑动到的位置上。

期望解决: 我想知道如何实现在切换时丝滑的让shopIndexGoodsList滚动回到顶部,itemHead2()依然保持吸顶状态,有专门的api吗?

如何使用

List({ scroller: this.scrollers }) {
    ListItemGroup()
    //其他内容 
    ListItemGroup({ header: this.itemHead2() }) {
        ListItem() {
            shopIndexGoodsList({
                pxZvp: this.pxZvp,
                otherGoodsList: this.otherGoodsList,
            })
            //商品列表的自定义组件
        }
    }

    @Builder itemHead2() {
        Row() {
            text("1").onClick(() => {
                ...
            })
            text('2').onClick(() => {
                ...
            })
            text("3").onClick(() => {
                ...
            })
        }.width('100%').height(80 * this.pxZvp).backgroundColor('#fff')
    }

更多关于HarmonyOS鸿蒙Next中arkui的list组件的ListItemGroup分组中内容切换后如何置顶的实战教程也可以访问 https://www.itying.com/category-93-b0.html

4 回复
import { hilog } from '@kit.PerformanceAnalysisKit'

@ComponentV2
struct Index {
  private listScroller: ListScroller = new ListScroller()
  private scrollIndex: number = 1 // 这个值根据 吸顶位置的Group算出来了,demo就是1,写死了

  build() {
    List({ scroller: this.listScroller }) {
      ListItemGroup {
        ListItem {
          Text("我是Top")
        }.height('200vp')
        .width('100%')
        .backgroundColor(Color.Brown)
      }

      ListItemGroup({ header: this.itemHead2() }) {
        ListItem {
          Column {
            Text("1").width('100%')
              .height('300vp')
              .backgroundColor(Color.Pink)
            Text("2").width('100%')
              .height('300vp')
              .backgroundColor(Color.Brown)
          }.height('1000vp')
          .width('100%')
          .backgroundColor(Color.Orange)
        }.height('1000vp')
      }
    }.size({ width: '100%', height: '100%' })
    .sticky(StickyStyle.Header)
  }

  @
  Builder
  itemHead2() {
    Row {
      Text("1")
      Text('2')
      Text("3")
    }
    .justifyContent(FlexAlign.SpaceBetween)
    .width('100%')
    .height(80)
    .backgroundColor('#fff')
    .onClick(() => {
      this.listScroller.scrollToIndex(this.scrollIndex, true)
    })
  }
}

更多关于HarmonyOS鸿蒙Next中arkui的list组件的ListItemGroup分组中内容切换后如何置顶的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


参考下面demo:

enum ScrollPosition {
  start,
  center,
  end
}

@Entry
@Component
struct NestedScroll {
  @State listPosition: number = ScrollPosition.start; // 0代表滚动到List顶部,1代表中间值,2代表滚动到List底部。
  @State scrollPosition: number = ScrollPosition.start; // 0代表滚动到页面顶部,1代表中间值,2代表滚动到页面底部。
  @State showTitle: boolean = false;
  @State currentYOffset: number = 0;
  @State arr: number[] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

  private scrollerForScroll: Scroller = new Scroller();
  private scrollerForList: Scroller = new Scroller();

  controller: TextInputController = new TextInputController()
  @State index : number = 0

  @Builder BarComponent(indexSelf : number, str1: string){
    Column(){
      Text(str1)
        .fontWeight(FontWeight.Medium)
        .fontColor(this.index === indexSelf ? Color.Red : Color.Black)
    }
  }

  build() {
    Stack({ alignContent: Alignment.Top }) {
      Scroll(this.scrollerForScroll) {
        Column() {
          Column(){}
            .width("100%")
            .height("40%")
            .backgroundColor(Color.Pink)
            Tabs({ barPosition: BarPosition.Start }) {
              TabContent() {
                List({ space: 10, scroller: this.scrollerForList }) {
                  ForEach(this.arr, (item: number) => {
                    ListItem() {
                      Text("促销商品" + item)
                        .width("100%")
                        .height("100%")
                        .borderRadius(15)
                        .fontSize(24)
                        .textAlign(TextAlign.Center)
                        .backgroundColor(Color.White)
                    }.width("100%").height(100)
                  }, (item: string) => item)
                }
                .padding({ left: 10, right: 10 })
                .width("100%")
                .edgeEffect(EdgeEffect.None)
                .scrollBar(BarState.Off)
                .onReachStart(() => {
                  this.listPosition = ScrollPosition.start
                })
                .onReachEnd(() => {
                  this.listPosition = ScrollPosition.end
                })
                .onScrollFrameBegin((offset: number, state: ScrollState) => {
                  if (!((this.listPosition == ScrollPosition.start && offset < 0)
                    || (this.listPosition == ScrollPosition.end && offset > 0))) {
                    this.listPosition = ScrollPosition.center
                  }
                  if (this.scrollPosition == ScrollPosition.end
                    && (this.listPosition != ScrollPosition.start || offset > 0)) {
                    return { offsetRemain: offset };
                  } else {
                    this.scrollerForScroll.scrollBy(0, offset)
                    return { offsetRemain: 0 };
                  }
                })
              }
              .tabBar(this.BarComponent(0,'打折促销'))
              TabContent() {
                List({ space: 10, scroller: this.scrollerForScroll }) {
                  ForEach(this.arr, (item: number) => {
                    ListItem() {
                      Text("行程安排" + item)
                        .width("100%")
                        .height("100%")
                        .borderRadius(15)
                        .fontSize(24)
                        .textAlign(TextAlign.Center)
                        .backgroundColor(Color.White)
                    }.width("100%").height(100)
                  }, (item: string) => item)
                }
                .padding({ left: 10, right: 10 })
                .width("100%")
                .edgeEffect(EdgeEffect.None)
                .scrollBar(BarState.Off)
                .onReachStart(() => {
                  this.listPosition = ScrollPosition.start
                })
                .onReachEnd(() => {
                  this.listPosition = ScrollPosition.end
                })
                .onScrollFrameBegin((offset: number, state: ScrollState) => {
                  if (!((this.listPosition == ScrollPosition.start && offset < 0)
                    || (this.listPosition == ScrollPosition.end && offset > 0))) {
                    this.listPosition = ScrollPosition.center
                  }
                  if (this.scrollPosition == ScrollPosition.end
                    && (this.listPosition != ScrollPosition.start || offset > 0)) {
                    return { offsetRemain: offset };
                  } else {
                    this.scrollerForScroll.scrollBy(0, offset)
                    return { offsetRemain: 0 };
                  }
                })
              }
              .tabBar(this.BarComponent(1,'行程服务'))
            }
          }
        }
        .scrollBar(BarState.Off)
        .width("100%")
        .height("100%")
        .onScroll((xOffset: number, yOffset: number) => {
          this.currentYOffset = this.scrollerForScroll.currentOffset().yOffset;
          if (!((this.scrollPosition == ScrollPosition.start && yOffset < 0)
            || (this.scrollPosition == ScrollPosition.end && yOffset > 0))) {
            this.scrollPosition = ScrollPosition.center
          }
        })
        .onScrollEdge((side: Edge) => {
          if (side == Edge.Top) {
            this.scrollPosition = ScrollPosition.start
          } else if (side == Edge.Bottom) {
            this.scrollPosition = ScrollPosition.end
          }
        })
        .onScrollFrameBegin(offset => {
          if (this.scrollPosition == ScrollPosition.end) {
            return { offsetRemain: 0 };
          } else {
            return { offsetRemain: offset };
          }
        })
        if (this.currentYOffset+50 >= 0) {
          Row() {
            TextInput({ text: 'xxxxxxxx', placeholder: 'input your word...', controller: this.controller }).fontSize(24)
          }
          .justifyContent(FlexAlign.Center)
          .backgroundColor('#00ffffff')
          .width('100%')
          .height('8%')
        }
      }
    }
    .width('100%')
    .height('100%')
    .backgroundColor(0xDCDCDC)
  }
}

在HarmonyOS鸿蒙Next中,使用ArkUI的List组件的ListItemGroup进行分组时,若需要在内容切换后将某一分组置顶,可以通过调整数据源中的分组顺序来实现。具体步骤如下:

  1. 获取数据源:确保List组件的数据源是一个可变的数组,通常是一个Array对象,包含多个ListItemGroup分组。

  2. 更新数据源顺序:当需要将某一分组置顶时,直接修改数据源中该分组的索引位置,将其移动到数组的第一个位置。

  3. 刷新UI:通过调用List组件的update方法或重新绑定数据源,触发UI刷新,使分组顺序的变更生效。

例如,假设有一个包含多个分组的数据源listData,其中每个分组是一个ListItemGroup对象。若要将第n个分组置顶,可以通过以下代码实现:

// 假设listData是数据源数组
let listData = [group1, group2, group3, ..., groupN];

// 将第n个分组置顶
let targetGroup = listData.splice(n, 1)[0]; // 从原位置移除
listData.unshift(targetGroup); // 插入到数组首位

// 刷新List组件
list.update(); // 假设list是List组件的实例

通过这种方式,可以实现ListItemGroup分组在内容切换后的置顶效果。

在HarmonyOS的ArkUI中,若要在ListItemGroup分组内容切换后将特定项置顶,可以通过List组件的scrollToIndex方法实现。首先,确保为ListItem设置唯一的id,然后调用scrollToIndex,传入目标项的索引值,即可将该项滚动到列表顶部。示例代码如下:

listRef.scrollToIndex({
  index: targetIndex,
  align: ListItemAlign.Start
});

其中,listRefList组件的引用,targetIndex为要置顶项的索引。

回到顶部