HarmonyOS ArkUi Tabs+TabContent+List实现tab吸顶功能

Demo效果

javascript 复制代码
@Entry
@Component
struct StickyNestedScroll {
  @State message: string = 'Hello World'
  @State arr: number[] = []
  scroller = new Scroller()

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

  build() {
    Scroll(this.scroller) {
      Column() {
        Stack({ alignContent: Alignment.Top }) {
          Column() {

          }.height("200vp").width('100%').backgroundImage($r('app.media.icon_home_top'))
          // Text('吸顶').width('100%').height(40).backgroundColor(Color.Black).zIndex(999)
        }


        Tabs({ barPosition: BarPosition.Start }) {
          TabContent() {
            List({ space: 10 }) {
              ForEach(this.arr, (item: number) => {
                ListItem() {
                  Text("item" + item)
                    .fontSize(16)
                }.listCard()
              }, (item: string) => item)
            }.width("100%")
            .edgeEffect(EdgeEffect.Spring)
            .nestedScroll({
              scrollForward: NestedScrollMode.PARENT_FIRST,
              scrollBackward: NestedScrollMode.SELF_FIRST
            })
          }.tabBar("Tab1")

          TabContent() {
          }.tabBar("Tab2")
        }
        .vertical(false)
        .backgroundColor(Color.Brown)
        .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)
    }
  }

  @Builder
  testHead() {
    Text('吸顶').width('100%').height(40).backgroundColor(Color.Black).zIndex(999)
  }
}

项目实战效果图

  • Tab:(企业统计)
javascript 复制代码
  @Builder
  TabWidget() {
    Row() {
      Text('企业统计')
        .fontColor($r('app.color.color303242')).fontSize(16).margin({ left: 12 })
    }
    .height('100%')
    .width('calc(100% - 30vp)')
    .borderRadius({ topLeft: 8, topRight: 8 })
    .backgroundColor(Color.White)
    .margin({ left: 15, right: 15 })
    .onClick(() => {
      this.scroller.scrollTo({ xOffset: 0, yOffset: 2000 })
    })
  }
  • 完整项目代码

仔细看代码里的注释

javascript 复制代码
@Entry
@Component
export struct HomePage {
  @State curIndex: number = 0
  scroller: Scroller = new Scroller()
  @State currentOffset: number = 0;
  @StorageLink('systemBarHeight') systemBarHeight: number = 0
  @State topOpacity: number = 1;
  @State searchHint: string = '请输入企业名称';
  @State banner?: BannerBean = new BannerBean()
  @State protMarketBean?: ProspectMarketBean[] = new Array<ProspectMarketBean>()

  aboutToAppear(): void {
 
  }

  build() {
    Stack({ alignContent: Alignment.Top }) {
      Scroll(this.scroller) {
        Column() {
          Column() {
           // tab 企业统计上面的组件   这里省略 l里面没内容的话 可以设置固定高度测试
           // ....
          }.width('100%')

          Tabs({ barPosition: BarPosition.Start }) {
            TabContent() {
            // 注意注意: 这里是tab 企业统计下面的界面  这里要用list
              List({ space: 10 }) {
                ListItem() {
                  Column() {
                    HomeWebWidget()
                    if (this.protMarketBean && this.protMarketBean.length > 0) {
                      HomeEnterpriseLib({ protMarketBean: this.protMarketBean }).margin({ top: 10 })
                    }
                  }.width('100%')
                }
              }.width("100%").height('100%')
              // edgeEffect  nestedScroll一定要设置
              .edgeEffect(EdgeEffect.Spring)
              .nestedScroll({
                scrollForward: NestedScrollMode.PARENT_FIRST,
                scrollBackward: NestedScrollMode.SELF_FIRST
              })
            }.tabBar(this.TabWidget())
          }
          .barWidth('100%')
          .barHeight(40)
          .vertical(false)
          .margin({ top: 10 })
           //60=搜索组件的高度 this.systemBarHeight= 状态栏的高度  这样吸顶才是刚好处于搜索组件下方  可自行调整
          .height(`calc(100% - ${60 + px2vp(this.systemBarHeight)}vp)`)
        }.width("100%")
        .backgroundImage($r('app.media.icon_home_top'))
        .backgroundImageSize({ width: '100%', height: '50%' })
      }
      .onScroll(() => {
      	// 滚动监听  根据偏移量 顶部搜索栏的界面效果
        this.currentOffset = this.scroller.currentOffset().yOffset;
        // 根据偏移控制透明度
        this.topOpacity = (140 - this.currentOffset) / 140; 例
      })
      .edgeEffect(EdgeEffect.Spring)
      .friction(0.6)
      .backgroundColor('#F3F3F3')
      .scrollBar(BarState.Off)
      .width('100%')
      .height('100%')
		// 滚动偏移量大于0时  显示顶部搜索
      if (this.currentOffset > 0) {
        this.SearchHeaderWidget()
      }
    }
  }

  @Builder
  TabWidget() {
    Row() {
      Text('企业统计')
        .fontColor($r('app.color.color303242')).fontSize(16).margin({ left: 12 })
    }
    .height('100%')
    .width('calc(100% - 30vp)') 
    .borderRadius({ topLeft: 8, topRight: 8 })
    .backgroundColor(Color.White)
    .margin({ left: 15, right: 15 })
    .onClick(() => {
      this.scroller.scrollTo({ xOffset: 0, yOffset: 2000 })
    })
  }

  @Builder
  SearchHeaderWidget() {

    Column() {
      Row() {
        Image($r('app.media.icon_search')).width(18).height(18).margin({ left: 15 })
        Text(this.searchHint).fontColor('#C6C9CF').fontSize(13).margin({ left: 8 })
      }
      .height(40)
      .width('100%')
      .backgroundColor(Color.White)
      .borderRadius(50)
      .onClick(() => {
        router.pushUrl({ url: RouterPath.SEARCH, params: { tabIndex: 1 } })
      })
      .margin({ top: px2vp(this.systemBarHeight) })
    }.backgroundColor('#0256FF')
    .padding({ left: 15, right: 15, bottom: 10, top: 10 })
    .opacity(1 - this.topOpacity) // 顶部搜索组件的透明度
  }
}
相关推荐
zhanshuo3 小时前
在鸿蒙里优雅地处理网络错误:从 Demo 到实战案例
harmonyos
zhanshuo3 小时前
在鸿蒙中实现深色/浅色模式切换:从原理到可运行 Demo
harmonyos
whysqwhw8 小时前
鸿蒙分布式投屏
harmonyos
whysqwhw9 小时前
鸿蒙AVSession Kit
harmonyos
whysqwhw11 小时前
鸿蒙各种生命周期
harmonyos
whysqwhw12 小时前
鸿蒙音频编码
harmonyos
whysqwhw12 小时前
鸿蒙音频解码
harmonyos
whysqwhw12 小时前
鸿蒙视频解码
harmonyos
whysqwhw12 小时前
鸿蒙视频编码
harmonyos
ajassi200012 小时前
开源 Arkts 鸿蒙应用 开发(十八)通讯--Ble低功耗蓝牙服务器
华为·开源·harmonyos