HarmonyOS鸿蒙Next中如何实现带有自定义TabBar的Tabs页面?

HarmonyOS鸿蒙Next中如何实现带有自定义TabBar的Tabs页面? 我需要创建一个底部导航的主页面,TabBar 需要自定义样式,包括图标、文字和选中状态动画,如何实现?

3 回复

实现思路:

  1. 定义 Tab 项的数据结构:
interface TabItem {
  title: string;
  icon: Resource;
  iconSelected: Resource;
  color: string;
}
  1. 使用 @Builder 创建自定义 TabBar 项:
[@Builder](/user/Builder)
TabBarItem(tab: TabItem, index: number) {
  Column({ space: 4 }) {
    Image(this.currentIndex === index ? tab.iconSelected : tab.icon)
      .width(24)
      .height(24)
      .fillColor(this.currentIndex === index ? tab.color : '#999999')
    Text(tab.title)
      .fontSize(11)
      .fontColor(this.currentIndex === index ? tab.color : '#999999')
  }
}
  1. 使用 Tabs 组件并设置 barPosition 为底部:
Tabs({ barPosition: BarPosition.End, index: this.currentIndex }) {
  TabContent() { HomePage() }
    .tabBar(this.TabBarItem(this.tabs[0], 0))
}
  1. 完整示例代码:
interface TabItem {
  title: string;
  icon: Resource;
  iconSelected: Resource;
  color: string;
}

@Entry
@Component
struct MainPage {
  @State currentIndex: number = 0;
  @State tabScale: number[] = [1, 1, 1, 1];

  private tabs: TabItem[] = [
    { title: '首页', icon: $r('app.media.ic_home'), iconSelected: $r('app.media.ic_home_filled'), color: '#007AFF' },
    { title: '案例', icon: $r('app.media.ic_case'), iconSelected: $r('app.media.ic_case_filled'), color: '#FF9500' },
    { title: '速查', icon: $r('app.media.ic_quick'), iconSelected: $r('app.media.ic_quick_filled'), color: '#34C759' },
    { title: '我的', icon: $r('app.media.ic_mine'), iconSelected: $r('app.media.ic_mine_filled'), color: '#5856D6' }
  ];

  [@Builder](/user/Builder)
  TabBarItem(tab: TabItem, index: number) {
    Column({ space: 4 }) {
      Stack() {
        Column() {
          Image(this.currentIndex === index ? tab.iconSelected : tab.icon)
            .width(24)
            .height(24)
            .fillColor(this.currentIndex === index ? tab.color : '#999999')
        }
        .width(48)
        .height(32)
        .borderRadius(16)
        .backgroundColor(this.currentIndex === index ? tab.color + '15' : Color.Transparent)
        .justifyContent(FlexAlign.Center)
      }

      Text(tab.title)
        .fontSize(11)
        .fontWeight(this.currentIndex === index ? FontWeight.Medium : FontWeight.Normal)
        .fontColor(this.currentIndex === index ? tab.color : '#999999')
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
    .scale({ x: this.tabScale[index], y: this.tabScale[index] })
    .animation({ duration: 150, curve: Curve.EaseOut })
    .onTouch((event: TouchEvent) => {
      if (event.type === TouchType.Down) {
        this.tabScale[index] = 0.9;
      } else if (event.type === TouchType.Up || event.type === TouchType.Cancel) {
        this.tabScale[index] = 1;
      }
    })
  }

  build() {
    Column() {
      Tabs({ barPosition: BarPosition.End, index: this.currentIndex }) {
        TabContent() {
          Text('首页内容').fontSize(20)
        }
        .tabBar(this.TabBarItem(this.tabs[0], 0))

        TabContent() {
          Text('案例内容').fontSize(20)
        }
        .tabBar(this.TabBarItem(this.tabs[1], 1))

        TabContent() {
          Text('速查内容').fontSize(20)
        }
        .tabBar(this.TabBarItem(this.tabs[2], 2))

        TabContent() {
          Text('我的内容').fontSize(20)
        }
        .tabBar(this.TabBarItem(this.tabs[3], 3))
      }
      .barHeight(64)
      .barBackgroundColor('#FFFFFF')
      .onChange((index: number) => {
        this.currentIndex = index;
      })
    }
    .width('100%')
    .height('100%')
  }
}

更多关于HarmonyOS鸿蒙Next中如何实现带有自定义TabBar的Tabs页面?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS Next中,实现自定义TabBar的Tabs页面主要使用TabsTabContent和自定义组件。首先,使用@Builder或自定义组件构建TabBar内容。然后,在Tabs组件中,通过tabBar属性传入自定义的TabBar组件,TabContent则对应每个Tab页的内容。通过TabsController可以控制Tab页的切换和状态同步。

在HarmonyOS Next中实现自定义TabBar的Tabs页面,可以通过以下步骤完成:

  1. 使用TabsTabContent组件:首先创建基本的Tabs结构,但隐藏默认TabBar。

    Tabs({ barPosition: BarPosition.End }) {
      // TabContent内容
    }
    .barMode(BarMode.Fixed)
    .barWidth('100%')
    .barHeight(60)
    .onChange((index: number) => {
      // 处理Tab切换
    })
    
  2. 隐藏默认TabBar:通过样式将官方TabBar设为透明或隐藏。

    .barState(this.barState)
    // 在Styles中设置
    // .barStyle({ opacity: 0 })
    
  3. 创建自定义TabBar组件

    • 使用RowFlex布局实现底部栏
    • 每个Tab项包含图标(Image)、文字(Text)和可能的动画组件
    • 使用@State装饰器管理选中状态
  4. 实现选中状态动画

    • 图标切换:通过条件渲染不同图片
    • 文字样式变化:修改字体颜色、大小等属性
    • 添加动画效果:
      .animation({
        duration: 300,
        curve: Curve.EaseInOut
      })
      
  5. 关联Tabs与自定义TabBar

    • 通过@State变量同步当前选中索引
    • 自定义TabBar的点击事件调用TabsController的changeIndex方法
  6. 完整示例结构

    [@Entry](/user/Entry)
    [@Component](/user/Component)
    struct CustomTabPage {
      @State currentIndex: number = 0
      private tabsController: TabsController = new TabsController()
      
      build() {
        Column() {
          // 主要内容区域
          Tabs({ controller: this.tabsController }) {
            TabContent() { /* 页面1 */ }
            TabContent() { /* 页面2 */ }
          }
          .barMode(BarMode.Fixed)
          .barWidth(0)
          .barHeight(0)
          
          // 自定义TabBar
          Row() {
            ForEach(this.tabItems, (item, index) => {
              Column() {
                Image(this.currentIndex === index ? item.selectedIcon : item.icon)
                Text(item.text)
                  .fontColor(this.currentIndex === index ? '#007DFF' : '#666')
              }
              .onClick(() => {
                this.currentIndex = index
                this.tabsController.changeIndex(index)
              })
            })
          }
        }
      }
    }
    

关键点:

  • 使用TabsController控制Tab切换
  • 通过状态变量同步选中索引
  • 自定义组件实现灵活样式控制
  • 动画效果可通过属性动画或显式动画实现

这种方法完全控制TabBar的视觉表现,同时保持Tabs的内容切换功能。

回到顶部