img

案例介绍

本教程将介绍如何实现社交应用带徽标的标签页基础界面。我们将实现一个包含消息、联系人、发现和我的四个标签页的主界面,重点关注标签页的布局和基础样式设计。

代码实现

@Entry
@Component
struct BadgeTabContentExample {
  @State currentIndex: number = 0
  private tabsController: TabsController = new TabsController()
  
  // 标签页数据
  @State tabItems: Array<{
    title: string,
    icon: Resource,
    selectedIcon: Resource,
    badge: number | string | null
  }> = [
    { 
      title: '消息', 
      icon: $r('app.media.icon_message_normal'), 
      selectedIcon: $r('app.media.icon_message_selected'),
      badge: 12
    },
    { 
      title: '联系人', 
      icon: $r('app.media.icon_contacts_normal'), 
      selectedIcon: $r('app.media.icon_contacts_selected'),
      badge: null
    },
    { 
      title: '发现', 
      icon: $r('app.media.icon_discover_normal'), 
      selectedIcon: $r('app.media.icon_discover_selected'),
      badge: 'NEW'
    },
    { 
      title: '我的', 
      icon: $r('app.media.icon_profile_normal'), 
      selectedIcon: $r('app.media.icon_profile_selected'),
      badge: null
    }
  ]

  build() {
    Column() {
      // 顶部标题栏
      Row() {
        Text('社交应用')
          .fontSize(20)
          .fontWeight(FontWeight.Bold)
      }
      .width('100%')
      .height(56)
      .padding({ left: 16, right: 16 })
      .justifyContent(FlexAlign.Center)
      
      // 标签页
      Tabs({ controller: this.tabsController, index: this.currentIndex }) {
        // 消息标签页
        TabContent() {
          Column() {
            Text('消息页面')
              .fontSize(16)
          }
          .width('100%')
          .height('100%')
          .justifyContent(FlexAlign.Center)
        }
        .tabBar(this.TabBarWithBadge(0))
        
        // 联系人标签页
        TabContent() {
          Column() {
            Text('联系人页面')
              .fontSize(16)
          }
          .width('100%')
          .height('100%')
          .justifyContent(FlexAlign.Center)
        }
        .tabBar(this.TabBarWithBadge(1))
        
        // 发现标签页
        TabContent() {
          Column() {
            Text('发现页面')
              .fontSize(16)
          }
          .width('100%')
          .height('100%')
          .justifyContent(FlexAlign.Center)
        }
        .tabBar(this.TabBarWithBadge(2))
        
        // 我的标签页
        TabContent() {
          Column() {
            Text('我的页面')
              .fontSize(16)
          }
          .width('100%')
          .height('100%')
          .justifyContent(FlexAlign.Center)
        }
        .tabBar(this.TabBarWithBadge(3))
      }
      .vertical(false)
      .scrollable(true)
      .barMode(BarMode.Fixed)
      .barWidth('100%')
      .barHeight(56)
      .onChange((index: number) => {
        this.currentIndex = index
      })
      .width('100%')
      .layoutWeight(1)
    }
    .width('100%')
    .height('100%')
  }
  
  // 带徽标的标签栏项目
  @Builder
  TabBarWithBadge(index: number) {
    Badge({
      count: this.getBadgeValue(index),
      maxCount: 99,
      position: BadgePosition.RightTop,
      style: { color: '#FFFFFF', fontSize: 10, badgeSize: 16, badgeColor: '#FF0000' }
    }) {
      Column({ space: 4 }) {
        Image(this.currentIndex === index ? this.tabItems[index].selectedIcon : this.tabItems[index].icon)
          .width(24)
          .height(24)
        
        Text(this.tabItems[index].title)
          .fontSize(12)
          .fontColor(this.currentIndex === index ? '#0A59F7' : '#666666')
          .fontWeight(this.currentIndex === index ? FontWeight.Medium : FontWeight.Normal)
      }
      .width('100%')
      .height('100%')
      .justifyContent(FlexAlign.Center)
    }
  }
  
  // 获取徽标值
  getBadgeValue(index: number): number | string | null {
    return this.tabItems[index].badge
  }
}

代码详解

1. 标签页数据结构

@State tabItems: Array<{
  title: string,
  icon: Resource,
  selectedIcon: Resource,
  badge: number | string | null
}>

数据结构特点:

  • 标签页标题
  • 普通和选中状态图标
  • 可选的徽标值
  • 响应式数据管理

2. 标签页布局

Tabs({ controller: this.tabsController, index: this.currentIndex }) {
  TabContent() {
    // 标签页内容
  }
  .tabBar(this.TabBarWithBadge(0))
}
.vertical(false)
.scrollable(true)
.barMode(BarMode.Fixed)

布局特点:

  • 水平标签布局
  • 固定宽度模式
  • 自定义标签栏
  • 统一的高度设置

3. 徽标实现

@Builder
TabBarWithBadge(index: number) {
  Badge({
    count: this.getBadgeValue(index),
    maxCount: 99,
    position: BadgePosition.RightTop,
    style: { color: '#FFFFFF', fontSize: 10, badgeSize: 16, badgeColor: '#FF0000' }
  }) {
    Column({ space: 4 }) {
      // 标签内容
    }
  }
}

徽标特点:

  • 支持数字和文本
  • 最大值限制
  • 右上角定位
  • 统一的样式

4. 标签栏样式

Column({ space: 4 }) {
  Image(this.currentIndex === index ? this.tabItems[index].selectedIcon : this.tabItems[index].icon)
    .width(24)
    .height(24)
  
  Text(this.tabItems[index].title)
    .fontSize(12)
    .fontColor(this.currentIndex === index ? '#0A59F7' : '#666666')
}

样式特点:

  • 垂直布局排列
  • 图标文字组合
  • 选中状态区分
  • 统一的间距

总结

本教程展示了如何实现社交应用带徽标的标签页基础界面。通过合理的数据结构设计和布局实现,我们创建了一个包含徽标显示的标签页界面。重点关注了徽标的样式设计和标签页的布局结构,为后续添加交互功能奠定了基础。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐