HarmonyOS 列表页面上下滑动,tabbar那里自动停住悬浮,不使用Tabs组件的前提下,有什么好的方法实现

HarmonyOS 列表页面上下滑动,tabbar那里自动停住悬浮,不使用Tabs组件的前提下,有什么好的方法实现  -鸿蒙开发者社区

HarmonyOS
2024-12-25 14:06:37
浏览
收藏 0
回答 1
待解决
回答 1
按赞同
/
按时间
Excelsior_abit

参考示例如下:

@Entry
@Component
struct StickyNestedScroll {
  @Styles
  listCard() {
    .backgroundColor(Color.White)
    .height(72)
    .width("100%")
    .borderRadius(12)
  }

  @State textOffset: number = 0
  @State textMargin: number = 0
  scroller: Scroller = new Scroller()
  @State swiperOffset: number = 0
  @State top: number = 100
  @State visible: boolean = false
  @State visible1: Visibility = Visibility.Visible
  @State number1: number = 0
  @State XiDing: boolean = false
  private swiperController: SwiperController = new SwiperController()
  private data: MyDataSource = new MyDataSource([])
  private data1: MyDataSource = new MyDataSource([])
  private scrollerForScroll: Scroller = new Scroller()

  @Builder
  SwiperItem(item: string) {
    Column() {
      Text(item.toString())
        .width('100%')
        .height("100%")
        .backgroundColor(0xAFEEEE)
        .textAlign(TextAlign.Center)
        .fontSize(30)
    }.width('100%')
    .height(80)
    .margin({ left: 5, right: 5 })
    .backgroundColor(Color.White)
  }

  @Builder
  SwiperItem1(item: string) {
    Column() {
      Text(item.toString())
        .width('100%')
        .height("100%")
        .backgroundColor('#fff')
        .textAlign(TextAlign.Center)
        .fontSize(30)
    }.width('100%')
    .height(50)
    .margin({ left: 5, right: 5 })
    .backgroundColor(Color.White)
  }

  build() {
    Column() {
      TextInput({ placeholder: 'input your word...' })
        .width('95%')
        .height(40)
        .margin(10)
      // swiper组件在屏幕中完全不可见时的逻辑
      if (this.visible) {
        Swiper(this.swiperController) {
          LazyForEach(this.data, (item: string) => {
            this.SwiperItem1(item)
          }, (item: string) => item)
        }
        .displayCount(5)
        .indicator(false)
        .autoPlay(false)
        .cachedCount(2)
        .index(1)
        .itemSpace(0)
        .curve(Curve.Linear)
      }
      Scroll(this.scrollerForScroll) {
        Column() {
          Swiper(this.swiperController) {
            LazyForEach(this.data, (item: string) => {
              this.SwiperItem(item)
            }, (item: string) => item)
          }
          .margin({ top: this.swiperOffset })
          .displayCount(5)
          .indicator(false)
          .autoPlay(false)
          .cachedCount(2)
          .index(1)
          .itemSpace(0)
          .curve(Curve.Linear)

          Row({ space: 20 }) {
            Text('春节不打烊(高度50)')
          }
          .visibility(this.visible1)
          .width('100%')
          .height(50)
          .justifyContent(FlexAlign.Center)
          .backgroundColor(Color.Orange)
          .border({ radius: { topLeft: 20, topRight: 20 } })

          Row({ space: 20 }) {
            Text('男童')
            Text('女童')
          }
          .width('100%')
          .height(50)
          .justifyContent(FlexAlign.Center)
          .backgroundColor(Color.Gray)

          Row({ space: 20 }) {
            Text('¥100以下')
            Text('¥100-¥150')
            Text('¥150以上')
          }
          .width('100%')
          .height(50)
          .justifyContent(FlexAlign.Center)

          Stack({ alignContent: Alignment.Top }) {
            List({ scroller: this.scroller, space: 10 }) {
              LazyForEach(this.data1, (item: string, index: number) => {
                ListItem() {
                  Text("item" + item)
                    .fontSize(16)
                }.listCard()
                .onAppear(() => {
                  console.log('新数据', index)
                })
              }, (item: string) => item)
            }
            .width("100%")
            .backgroundColor(Color.Blue)
            .edgeEffect(EdgeEffect.None)
            .margin({ top: this.top })
            .onReachStart(() => {
              console.log('start')
              if (this.swiperOffset === -180) {
                this.XiDing = false
              }
            })
            // 黄色区域滑到一半,手指松开后黄色区域全部弹出
            .onScrollStop(() => {
              if (this.swiperOffset > -230 && this.swiperOffset && this.XiDing === true) {
                this.swiperOffset = -180
              }
            })
            .onScrollFrameBegin((offset: number, state: ScrollState) => {
              // console.log(`${offset}`)
              if (this.swiperOffset < -80) {
                this.visible = true
                this.visible1 = Visibility.None
              }
              if (this.swiperOffset > -80 && offset < 0) {
                this.visible = false
                this.visible1 = Visibility.Visible
              }
              if (this.swiperOffset - offset >= 0) {
                this.swiperOffset = 0
              } else {
                this.swiperOffset = this.swiperOffset - offset
              }
              // 第一次回滑正常后 this.XiDing 的值变成了false,会导致第二次及以后的回滑效果异常
              if (this.swiperOffset < -280) {
                this.swiperOffset = -280
                this.XiDing = true
              }
              // 这里不设 this.swiperOffset < 0 的话,初次进入页面下拉就会出现页面布局异常
              if (this.swiperOffset > -180 && offset < 0 && this.XiDing === true) {
                // console.log('不准动!!!')
                this.swiperOffset = -180
              }
              if (this.swiperOffset != -280 && this.swiperOffset != 0 && this.swiperOffset != -180) {
                return {
                  offsetRemain: 0
                }
              }
              return {
                offsetRemain: offset
              }
            })

            // 上滑需要回滑的部分
            Column() {
              Row({ space: 20 }) {
                Text('销量')
                Text('价格')
                Text('筛选')
              }
              .width('100%')
              .height(50)
              .justifyContent(FlexAlign.Center)
              .backgroundColor(Color.Yellow)

              Row({ space: 20 }) {
                // Text('筛选')
                // Text('春节不打烊')
                Text('swiper:' + `${this.swiperOffset}`)
                Text('XiDing:' + `${this.XiDing}`)
              }
              .backgroundColor(Color.Red)
              .width('100%')
              .height(50)
              .justifyContent(FlexAlign.Center)
            }
            .offset({
              y: this.textOffset
            })
            .margin({ top: this.textMargin })
          }.width("100%").height('100%')
        }
      }
    }
    .backgroundColor(Color.Pink)
  }

  aboutToAppear() {
    let list: number[] = []
    for (let i = 1; i <= 10; i++) {
      list.push(i);
    }
    this.data = new MyDataSource(list)
    let list1: number[] = []
    for (let i = 0; i <= 30; i++) {
      list1.push(i);
    }
    this.data1 = new MyDataSource(list1)
  }
}

class MyDataSource implements IDataSource {
  private list: number[] = []

  constructor(list: number[]) {
    this.list = list
  }

  totalCount(): number {
    return this.list.length
  }

  getData(index: number): number {
    return this.list[index]
  }

  registerDataChangeListener(listener: DataChangeListener): void {
  }

  unregisterDataChangeListener() {
  }
}
分享
微博
QQ
微信
回复
2024-12-25 16:36:03
相关问题
键盘拉起时列表无法上下滑动
3106浏览 • 1回复 待解决
页面截图功能,什么方法
1884浏览 • 2回复 待解决
Tabs组件tabBar,能否设置对齐方法
1450浏览 • 1回复 待解决
服务卡片可以响应上下滑动操作吗?
7954浏览 • 2回复 待解决
HarmonyOS Tabs组件tabBar宽度问题
1658浏览 • 1回复 待解决
Listitem点击变色什么方法
3534浏览 • 1回复 待解决