鸿蒙开发自定义TabLayout和TabPager联动

鸿蒙开发自定义TabLayout和TabPager联动

鸿蒙开发TabLayout和TabPager联动,类似Android的SlidingTabLayout和ViewPaer

一、效果图:

在这里插入图片描述

二、思路:

自定义组件TabLayout和TabPager

三、关键代码:
@Component
export struct TabLayout {
  @ObjectLink mediator: TabLayoutPagerMediator
  @State tabItemWidth: number = 0
  @BuilderParam TabItemBuilder: (item: TabItem) => void
  @BuilderParam TabIndicatorBuilder: () => void
  indexChanged?: (item: number) => void
  showIndicator: boolean = true

  build() {
    Stack({ alignContent: Alignment.BottomStart }) {
      Row() {
        ForEach(this.mediator.tabItems, (item: TabItem, index:number) => {
          Stack({ alignContent: Alignment.Center }) {
            if (this.TabItemBuilder) {
              this.TabItemBuilder(item)
            } else {
              this.DefaultTabItemBuilder(item)
            }
          }.layoutWeight(1)
          .onAreaChange((_, newValue: Area) => {
            this.tabItemWidth = newValue.width as number
          })
          .onClick(() => {

              this.indexChanged?.(item.index)
              this.mediator.jumpToIndex(item.index)

          })
        }, (item:TabItem) => `${item.index}-${JSON.stringify(item)}`)
      }

      if (this.showIndicator) {
        Stack({ alignContent: Alignment.Bottom }) {
          if (this.TabIndicatorBuilder) {
            this.TabIndicatorBuilder()
          } else {
            this.DefaultTabIndicatorBuilder()
          }
        }
        .offset({ x: this.getIndicatorOffsetX() })
        .width(this.tabItemWidth)
      }
    }
  }

  getIndicatorOffsetX():number{
    //logContent("getIndicatorOffsetX",`${this.mediator.currentIndex} - ${this.tabItemWidth} - ${this.mediator.currentIndex * this.tabItemWidth}`)
    return this.mediator.currentIndex * this.tabItemWidth
  }

  @Builder
  DefaultTabItemBuilder(item: TabItem) {
    Text(item.name)
      .fontSize(SizeConstant.TEXT_L)
      .fontColor(this.mediator.currentIndex === item.index
        ? $r('app.color.color_222')
        : $r('app.color.color_555'))
      .textAlign(TextAlign.Center)
      .fontWeight(FontWeight.Bold)
      .height(SizeConstant.TAB_LAYOUT_HEIGHT)
  }

  @Builder
  DefaultTabIndicatorBuilder() {
    Divider()
      .strokeWidth(SizeConstant.TAB_LAYOUT_INDICATOR_HEIGHT)
      //.margin({ bottom: SizeConstant.SPACE_S })
      .color($r('app.color.color_main'))
      .width(SizeConstant.TAB_LAYOUT_INDICATOR_WIDTH)
      .lineCap(LineCapStyle.Round)
      .align(Alignment.Bottom)
  }
}
四、项目demo源码结构图:

在这里插入图片描述
有需要完整源码demo的私信我,我每天都看私信的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

893151960

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值