HarmonyOS 点击滚动吸顶效果?

@Entry
@Component
struct Index {
  @State arr: number[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14]
  build() {
    Scroll() {
      Column() {
        Text("Scroll第一部分 Area")
          .width("100%")
          .height(200)
          .backgroundColor('#0080DC')
          .textAlign(TextAlign.Center)
        Column(){
          // 第二部分吸顶效果主要是通过设置nestedScroll属性以及父组件设置高度100%引起的
          // 无论多段内容,只需要将吸顶内容与list组件放入同一个父容器中.且为最后一段内容即可形成该效果
          Text("Scroll第二部分 Area").width("100%").height(100).backgroundColor(Color.Transparent)
            .textAlign(TextAlign.Center).fontColor(Color.Black)
          List({ space: 10 }) {
            ForEach(this.arr, (item: number) => {
              ListItem() {
                Text("item" + item).fontSize(16).height(72).width('100%').border({width:1}).fontColor(Color.Black)
              }
            }, (item: string) => item)
          }.width("100%")
          .height("calc(100% - 100vp)").backgroundColor(Color.Blue)
          .edgeEffect(EdgeEffect.Spring)
          .nestedScroll({
            scrollForward: NestedScrollMode.PARENT_FIRST,
            scrollBackward: NestedScrollMode.SELF_FIRST
          })
        }.height("100%")
      }.width("100%")
    }
    .edgeEffect(EdgeEffect.Spring)
    .friction(0.6)
    .backgroundColor(Color.White)
    .scrollBar(BarState.Off)
    .width('100%')
    .height('100%')
  }
}

吸顶效果已实现,但是如何点击吸顶部分的组件时,如何触发滚动到吸顶位置呢,如点击demo中的Text("Scroll第二部分 Area")组件,就触发到吸顶效果?

上面demo中如何获取Text("Scroll第二部分 Area")离Scroll顶部的高度

阅读 487
1 个回答

1、利用Scroller控制scroll移动位置:

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

2、利用onAreaChange实时获取距离屏幕顶部高度:

https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/ts-universal-component-area-change-event-V5\#onareachange

@Entry
@Component
struct Index1 {
  @State arr: number[] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14];
  private scroller: Scroller = new Scroller();
  private partOneHeight: number = 200;
  private partTowPositionY: number = 0;

  build() {
    Scroll(this.scroller) {
      Column() {
        Text("Scroll第一部分 Area")
          .width("100%")
          .height(this.partOneHeight)
          .backgroundColor('#0080DC')
          .textAlign(TextAlign.Center)
        Column() {
          // 第二部分吸顶效果主要是通过设置nestedScroll属性以及父组件设置高度100%引起的
          // 无论多段内容,只需要将吸顶内容与list组件放入同一个父容器中.且为最后一段内容即可形成该效果
          Text("Scroll第二部分 Area")
            .width("100%")
            .height(100)
            .backgroundColor(Color.Transparent)
            .textAlign(TextAlign.Center)
            .fontColor(Color.Black)
            .onAreaChange((oldValue: Area, newValue: Area)=>{
              this.partTowPositionY = Number(newValue.globalPosition.y);
            })
            .onClick(() => {
              this.scroller.scrollTo({
                xOffset: 0, yOffset: this.partOneHeight, animation: {
                  duration: 1000
                }
              })
            })
          List({ space: 10 }) {
            ForEach(this.arr, (item: number) => {
              ListItem() {
                Text("item" + item)
                  .fontSize(16)
                  .height(72)
                  .width('100%')
                  .border({ width: 1 })
                  .fontColor(Color.White)
              }
            }, (item: string) => item)
          }
          .width("100%")
          .height("calc(100% - 100vp)")
          .backgroundColor(Color.Red)
          .edgeEffect(EdgeEffect.Spring)
          .nestedScroll({
            scrollForward: NestedScrollMode.PARENT_FIRST,
            scrollBackward: NestedScrollMode.SELF_FIRST
          })
        }.height("100%")
      }.width("100%")
    }
    .onScrollStop(()=>{
      if (this.partTowPositionY <= this.partOneHeight / 2) {
        this.scroller.scrollTo({
          xOffset: 0, yOffset: this.partOneHeight, animation: {
            duration: 1000
          }
        })
      } else {
        this.scroller.scrollTo({
          xOffset: 0, yOffset: 0, animation: {
            duration: 1000
          }
        })
      }
    })
    .edgeEffect(EdgeEffect.Spring)
    .friction(0.6)
    .backgroundColor(Color.White)
    .scrollBar(BarState.Off)
    .width('100%')
    .height('100%')
  }
}

至于如何获取 Text("Scroll第一部分 Area")的高度

使用onAreaChange,参考链接:

https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/ts-universal-component-area-change-event-V5\#onareachange