【HarmonyOS NEXT】自定义Tabs使其中间项突出显示

【问题描述】
要求中间的tabBar突出到内容处

【效果图】
文档截图

【解决思路】

  1. 使用Stack让中间项有能力突破tabBar区域
  2. 使用Canvas绘制曲线

【核心代码】

@Entry
@Component
struct BuilderModifierCase {
  private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(
    new RenderingContextSettings(true)
  )

  @Builder
  getTabBarItem(item: TabBarInterface, index: number) {
    Column({ space: 4 }) {
      if (item.name === 'door') {
        Row()
          .width(20)
          .aspectRatio(1)
      } else {
        Image(this.currentIndex === index ? item.selectIcon : item.icon)
          .width(20)
          .aspectRatio(1)
      }
      Text(item.title)
        .fontColor(this.currentIndex === index ? Color.Orange : Color.Gray)
        .zIndex(10)
    }
  }

  build() {
    Stack({ alignContent: Alignment.Bottom }) {
      Tabs({ barPosition: BarPosition.End, index: $$this.currentIndex }) {
        ForEach(this.tabBarList, (item: TabBarInterface, index) => {
          TabContent() {
            Column() {
              Text(index + '-' + this.currentIndex)
              Text()
              Text(item.title)
            }
          }.tabBar(this.getTabBarItem(item, index))
          .border({
            width: { bottom: 1 },
            color: $r('app.color.top_border_color')
          })
        })
      }

      Stack({ alignContent: Alignment.Top }) {
        Canvas(this.context)
          .height('80%')
          .backgroundColor(Color.White)
          .onReady(() => {
            const LINE_WIDTH = 1
            const LINE_OFFSET = 17.5
            this.context.strokeStyle = '#e4e4e4'
            this.context.lineWidth = LINE_WIDTH

            // 画圆弧
            this.context.beginPath();
            this.context.arc(
              IMAGE_BOX_WIDTH / 2,
              IMAGE_BOX_WIDTH / 2 + LINE_WIDTH,
              IMAGE_BOX_WIDTH / 2,
              3.14 + RADIAN_OFFSET,
              6.28 - RADIAN_OFFSET
            );
            this.context.stroke();

            // 左边补短横线
            this.context.beginPath();
            this.context.moveTo(0, LINE_OFFSET);
            this.context.lineTo(1, LINE_OFFSET);
            this.context.stroke();

            // 右边补短横线
            this.context.beginPath();
            this.context.moveTo(IMAGE_BOX_WIDTH - 1, LINE_OFFSET);
            this.context.lineTo(IMAGE_BOX_WIDTH, LINE_OFFSET);
            this.context.stroke();
          })
        Image(this.currentIndex === DOOR_BAR_INDEX ? this.doorBarItem.selectIcon : this.doorBarItem.icon)
          .width(40)
          .aspectRatio(1)
          .backgroundColor(Color.Orange)
          .borderRadius(20)
          .padding(8)
          .margin({ top: 5 })
      }
      .width(IMAGE_BOX_WIDTH)
      .aspectRatio(1)
      .margin({ bottom: 24 })
      .onClick(() => {
        this.currentIndex = DOOR_BAR_INDEX
      })
    }
  }
}

【新版本】
【HarmonyOS NEXT】自定义Tabs使其中间项突出显示2

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值