HarmonyOS 鸿蒙Next中关于Tabs的使用

HarmonyOS 鸿蒙Next中关于Tabs的使用 如果要在tab左右有其他组件,如返回键,为啥用Row无法实现,只能用stack。如下面代码

NavDestination() {
  Stack({alignContent: Alignment.TopStart}) {
    Row() {
      Image($r('sys.media.ohos_ic_public_arrow_left'))
        .width(28)
        .height(28)
        .fillColor($r('app.color.subtitle1'))
        .onClick(() => {
          this.appPathStack.pop()
        })
    }
    .width(36)
    .height(52)
    .zIndex(1)

    Column() {
      Tabs({
        index: this.currentIndex,
        // 默认底部
        barPosition: BarPosition.Start,
        controller: this.tabsController
      }) {
        TabContent() {
          List() {
            ListItem() {
              Column() {
                Text('home')
                  .fontSize(18 * this.textScaleFactor)
                  .fontColor($r('app.color.subtitle1'))
                  .fontWeight(FontWeight.Bold)
                  .textAlign(TextAlign.Center)
              }
              .width('100%')
              .height('180%')
            }
          }
          // 是否显示滚动条 默认 Auto
          .scrollBar(BarState.Off)
          .width('100%')
          .height('100%')
        }
        .tabBar(this.tabBuilder(0, $r('app.string.bottomNavigationBarHome')))

        TabContent() {
          List() {
            ListItem() {
              Column() {
                Text('me')
                  .fontSize(18 * this.textScaleFactor)
                  .fontColor($r('app.color.subtitle1'))
                  .fontWeight(FontWeight.Bold)
                  .textAlign(TextAlign.Center)
              }
              .width('100%')
              .height('180%')
            }
          }
          // 是否显示滚动条 默认 Auto
          .scrollBar(BarState.Off)
          .width('100%')
          .height('100%')
        }
        .tabBar(this.tabBuilder(1, $r('app.string.bottomNavigationBarMe')))
      }
      // 分割线 set the divider between tab bar and tab content.
      .divider({ strokeWidth: 0.5, color: $r('app.color.dividerColor')})
      .layoutWeight(1)
      .barHeight(52)
      // 固定导航栏
      .barMode(BarMode.Fixed)
      // 是否允许滚动
      .scrollable(true)
      .backgroundColor($r('app.color.backgroundColor'))
      .onChange((index) => {
        this.currentIndex = index;
        this.tabsController.changeIndex(index)
      })
      // 切换动画开始时触发该回调。下划线跟着页面一起滑动,同时宽度渐变。
      .onAnimationStart((targetIndex: number) => {
        this.currentIndex = targetIndex;
        this.tabsController.changeIndex(targetIndex)
      })
    }
    .layoutWeight(1)
  }
}
.backgroundColor($r('app.color.backgroundColor'))
.padding({
  top: AppStorage.get<number>('statusBarHeight'),
  bottom: AppStorage.get<number>('naviIndicatorHeight')
})
.width('100%')
.height('100%')
// 去掉隐藏的带返回键的标题栏
.hideTitleBar(true)

更多关于HarmonyOS 鸿蒙Next中关于Tabs的使用的实战教程也可以访问 https://www.itying.com/category-93-b0.html

3 回复

Tabs 组件默认会尝试横向填充父容器剩余空间。当使用 Row 包裹时,Tabs 会直接撑满剩余宽度,导致左右无法插入其他组件。

更多关于HarmonyOS 鸿蒙Next中关于Tabs的使用的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS Next中,Tabs组件用于实现内容分类切换。它通常与TabContent搭配使用,通过@State装饰器管理当前选中的索引。开发者需在Tabs内为每个TabContent设置对应的tabBar项,并通过onChange事件监听标签页切换。布局支持垂直或水平方向,可自定义标签栏样式与内容区滚动行为。

在HarmonyOS Next中,Tabs组件默认会占据其父容器的全部可用空间,特别是在设置了.layoutWeight(1)的情况下。当使用Row布局时,Tabs会横向扩展并挤压同级的其他组件(如返回按钮),导致布局不符合预期。

使用Stack布局是正确的解决方案,原因如下:

  1. 层叠定位Stack允许子组件通过.zIndex()进行层叠控制,可以将返回按钮定位在Tabs上方,而不影响Tabs的布局空间。

  2. 布局独立性:在Stack中,返回按钮的Row容器和TabsColumn容器是独立定位的。返回按钮通过固定尺寸和Alignment.TopStart对齐到左上角,而Tabs仍可正常使用.layoutWeight(1)充满剩余空间。

  3. 代码示例分析:您的代码中,Stack包含两个子组件:

    • 第一个是返回按钮的Row,设置了固定宽高和zIndex(1)确保悬浮在上层。
    • 第二个是包含TabsColumn,通过.layoutWeight(1)占满屏幕,Tabs在其内部正常渲染。

如果强制使用Row实现,需要为Tabs和返回按钮精确计算宽度比例,且难以处理动态布局(如横竖屏切换)。Stack方案更简洁可靠,是HarmonyOS Next中实现此类覆盖式布局的推荐方式。

回到顶部