List容器组件是否能够提供half sticky模式?

结果页的列表流中会需要支持half sticky的模式,当瀑布流下滑的时候搜索框和带有“综合,销量等”的排序条会快速隐藏,当瀑布流上滑的时候,搜索框和排序条不用等到滑倒顶部就可以展示。

阅读 469
1 个回答
enum ScrollPosition {
  start,
  center,
  end
}

@Entry
@Component
struct Index2 {
  @State listPosition: number = ScrollPosition.start
  @State scrollPosition: number = ScrollPosition.start
  @State showTitle: boolean = false
  @State currentYOffset: number = 0
  @State currentScrollOffsetInList: number = 0
  private currentScrollStateInList: ScrollState | null = null
  @State msg1: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
  @State msg2: string[] = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
  @State msg3: string[] = ['aa', 'bb', 'cc', 'dd', 'ee', 'ff', 'gg', 'hh', 'ii', 'jj']
  private scrollerForScroll: Scroller = new Scroller()
  private scrollerForList: Scroller = new Scroller()
  scrollGetData: number[] = []
  private lastOffset: number = 0

  build() {
    Stack({ alignContent: Alignment.Top }) {
      Scroll(this.scrollerForScroll) {
        Column() {
          Image($r('app.media.cat'))
            .width('100%')
            .height('40%')
          Tabs({ barPosition: BarPosition.Start }) {
            TabContent() {
              Column() {
                List({ space: 10, scroller: this.scrollerForList }) {
                  ForEach(this.msg3, (item: string) => {
                    ListItem() {
                      Text('ListItem' + 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 };
                  }
                })
                .onScroll((scrollOffset: number, scrollState: ScrollState) => {
                  this.currentScrollOffsetInList = scrollOffset
                  this.currentScrollStateInList = scrollState

                  if (scrollOffset != 0) {
                    this.lastOffset = scrollOffset
                  }
                  //记录打印0前的最后一个值
                  console.log(this.lastOffset + ' this.lastOffset')

                  console.log(scrollOffset + '');
                  (scrollOffset <= 0 && this.lastOffset < 0) ? this.showTitle = true : this.showTitle = false
                })

              }

            }.tabBar('促销活动')

            TabContent() {
              Column().width('100%').height('100%').backgroundColor('#007DFF')
            }.tabBar('行程服务')

          }
          .vertical(false)
          .barMode(BarMode.Fixed)
          .barWidth(360)
          .barHeight(56)
          .width("100%")

          .height("92%")
          .backgroundColor('#F1F3F5')
        }
      }
      .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.showTitle) {
        Stack() {
          Row() {
            Text('发现')
              .fontSize(24)
          }
          .justifyContent(FlexAlign.Center)
        }
        .backgroundColor(Color.Red)
        .width('100%')
        .height('8%')

      }
    }
    .width('100%')
    .height('100%')
    .backgroundColor(0xDCDCDC)
  }
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进