HarmonyOS 鸿蒙Next中使用 Badge 组件显示角标

HarmonyOS 鸿蒙Next中使用 Badge 组件显示角标 在移动应用中,我们经常需要在图标或按钮的角落显示一个小红点或数字,以提示用户有新的消息、待办事项或更新。这个小小的“角标”是吸引用户注意力、引导用户交互的有效手段。

虽然我们也可以通过 Stack 布局手动将一个 Text 叠加在 Image 上来实现类似效果,但这种方式代码繁琐且难以维护。

所以我们应该如何使用 Badge 组件来快速并简单的显示角标呢?

3 回复

使用场景

Badge 组件的应用场景非常直观,比如我们在应用的消息/通知中心图标上显示未读消息数量,

又比如我们在在购物车图标上显示已添加的商品数量,再比如在列表项上显示未完成的子任务数量。

实现思路

第一步:创建基础组件,首先,创建一个你想要附加角标的组件,通常是一个 Image(图标)或 Text(文字)。这个组件将作为角标的载体。

第二步:用 Badge 包裹基础组件:在ArkUI的 build() 方法中,将基础组件作为 Badge 组件的子组件。例如:Badge({ content: ‘…’, count: 1 }) { Image(…) }。

第三步:配置角标内容和样式,通过Badge 组件的多个属性来定制角标。

第四步:动态更新角标状态,在组件中定义一个 @State 变量(如 messageCount: number = 0)来存储角标的数值。将 Badge 的 count 属性绑定到这个 @State 变量上。当应用逻辑(如接收到新消息)更新 messageCount 的值时,Badge 组件会自动响应变化,更新显示的数字。

实现效果

图片

完整实现代码

// BadgeDemoPage.ets
import promptAction from '@ohos.promptAction';

@Entry
@Component
struct BadgeDemoPage {
  [@State](/user/State) messageCount: number = 5;
  [@State](/user/State) cartCount: number = 0;
  [@State](/user/State) selectedTabIndex: number = 0;
  [@State](/user/State) hasUpdate: boolean = true;

  // 修改后的 @Builder,不再接收 badgeCount 参数
  @Builder
  BottomBarItem(icon: Resource, title: string, index: number) {
    Column() {
      Badge({
        count: this.getBadgeCount(index),
        position: BadgePosition.RightTop,
        style: {
          color: Color.White,
          fontSize: 10,
          badgeSize: 16,
          badgeColor: '#FA2A2D'
        }
      }) {
        Image(icon)
          .width(28)
          .height(28)
          .fillColor(this.selectedTabIndex === index ? '#007DFF' : '#999999')
      }
      Text(title)
        .fontSize(12)
        .margin({ top: 4 })
        .fontColor(this.selectedTabIndex === index ? '#007DFF' : '#999999')
    }
    .justifyContent(FlexAlign.Center)
    .onClick(() => {
      this.selectedTabIndex = index;
      switch (index) {
        case 1: // 消息
          this.messageCount = 0;
          promptAction.showToast({ message: '所有消息已标记为已读' });
          break;
        case 2: // 购物车
          promptAction.showToast({ message: `购物车有 ${this.cartCount} 件商品` });
          break;
        case 3: // 我的
          if (this.hasUpdate) {
            this.hasUpdate = false;
            promptAction.showToast({ message: '您有新的系统更新' });
          } else {
            promptAction.showToast({ message: '进入我的页面' });
          }
          break;
        default:
          promptAction.showToast({ message: '已在首页' });
          break;
      }
    })
  }

  // 新增一个辅助函数,让 @Builder 内部逻辑更清晰
  private getBadgeCount(index: number): number {
    switch (index) {
      case 1: // 消息
        return this.messageCount;
      case 2: // 购物车
        return this.cartCount;
      case 3: // 我的
        return this.hasUpdate ? 1 : 0;
      default:
        return 0;
    }
  }

  build() {
    Column() {
     
      Row() {
        Text('Badge 组件演示')
          .fontSize(20)
          .fontWeight(FontWeight.Medium)
      }
      .width('100%')
      .height(56)
      .backgroundColor(Color.White)
      .justifyContent(FlexAlign.Center)
      .shadow({ radius: 4, color: '#1F000000', offsetY: 2 })

      Scroll() {
        Column() {
          Text('状态信息卡片')
            .fontSize(18)
            .fontWeight(FontWeight.Bold)
            .margin({ bottom: 20 })

          Column() {
            Row() {
              Text('未读消息')
                .fontSize(16)
              Text(`${this.messageCount} 条`)
                .fontSize(16)
                .fontColor(this.messageCount > 0 ? '#FA2A2D' : '#999999')
            }
            .width('100%')
            .justifyContent(FlexAlign.SpaceBetween)
            .padding({ top: 12, bottom: 12 })

            Divider().color('#F1F3F5')

            Row() {
              Text('购物车商品')
                .fontSize(16)
              Text(`${this.cartCount} 件`)
                .fontSize(16)
                .fontColor(this.cartCount > 0 ? '#FA2A2D' : '#999999')
            }
            .width('100%')
            .justifyContent(FlexAlign.SpaceBetween)
            .padding({ top: 12, bottom: 12 })
          }
          .width('100%')
          .backgroundColor(Color.White)
          .borderRadius(12)
          .padding({ left: 20, right: 20 })
          .shadow({ radius: 8, color: '#1A000000', offsetX: 0, offsetY: 4 })
        }
        .width('100%')
        .padding(16)
      }
      .layoutWeight(1)
      .backgroundColor('#F5F5F5')

      // 底部导航栏调用方式也相应改变
      Row() {
        this.BottomBarItem($r('sys.media.ohos_user_auth_icon_face'), '首页', 0)
        this.BottomBarItem($r('sys.media.ohos_user_auth_icon_face'), '消息', 1)
        this.BottomBarItem($r('sys.media.ohos_user_auth_icon_face'), '购物车', 2)
        this.BottomBarItem($r('sys.media.ohos_user_auth_icon_face'), '我的', 3)
      }
      .width('100%')
      .height(60)
      .backgroundColor(Color.White)
      .justifyContent(FlexAlign.SpaceEvenly)
      .border({ width: { top: 0.5 }, color: '#E5E5E5' })
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.SpaceBetween)
  }

  onPageShow() {
    setTimeout(() => {
      this.messageCount++;
    }, 2000);
    setTimeout(() => {
      this.cartCount++;
    }, 3000);
  }
}

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


在HarmonyOS Next中,Badge组件用于在应用图标或控件上显示角标,如未读消息数。它支持数字、文本或圆点形式的角标,可通过count属性设置数值,maxCount限制最大值,style自定义样式(如颜色、尺寸)。Badge可嵌套在Button、Image等组件内,通过position调整角标位置。开发者需导入@ohos.arkui.advanced.Badge模块,并在布局中声明使用。

在HarmonyOS Next中,使用Badge组件显示角标是推荐且高效的方式。Badge@ohos.arkui.advanced.Components包提供的容器组件,用于在子组件右上角添加徽标。

基本用法: 将需要添加角标的组件作为Badge的子组件,通过参数控制角标内容与样式。

import { Badge, BadgeOptions } from '@ohos.arkui.advanced.Components';

@Entry
@Component
struct Index {
  build() {
    Column() {
      // 1. 数字角标
      Badge({
        count: 5,
        position: BadgePosition.RIGHT_TOP,
        style: { color: '#FFFFFF', backgroundColor: '#FA2A2D', fontSize: 12 }
      }) {
        Image($r('app.media.icon'))
          .width(50)
          .height(50)
      }

      // 2. 小红点角标
      Badge({
        count: 0, // count为0时显示红点
        position: BadgePosition.RIGHT_TOP
      }) {
        Button('消息')
          .width(80)
      }

      // 3. 文本角标
      Badge({
        value: 'NEW',
        style: { color: '#FFFFFF', backgroundColor: '#007DFF' }
      }) {
        Text('标签')
          .fontSize(16)
          .padding(10)
      }
    }
  }
}

关键参数说明:

  • count: 设置数字角标,为0时显示红点,超过maxCount时显示maxCount+
  • value: 设置文本角标,优先级高于count
  • position: 角标位置,如BadgePosition.RIGHT_TOP(默认)
  • style: 自定义角标样式,包括颜色、背景、字体等
  • maxCount: 最大显示数字,默认99

样式自定义示例:

Badge({
  count: 120,
  maxCount: 99,
  style: {
    color: '#FFF',
    backgroundColor: '#FF7500',
    fontSize: 10,
    badgeSize: 20,
    borderWidth: 1,
    borderColor: '#FFF'
  }
}) {
  // 子组件
}

相比手动使用Stack布局,Badge组件封装了位置计算、溢出处理、样式配置等逻辑,代码更简洁且易于维护。对于动态角标更新,只需响应式地修改countvalue参数即可。

回到顶部