HarmonyOS鸿蒙Next中如何实现统计数字卡片组件?

HarmonyOS鸿蒙Next中如何实现统计数字卡片组件? 我需要创建一个显示统计数据的卡片组件,支持图标、数值、标签和趋势指示,如何实现?

3 回复

实现思路:

  1. 定义组件属性,包括数值、标签、图标、颜色和趋势:
@Component
export struct StatCard {
  @Prop value: string = '0';
  @Prop label: string = '';
  @Prop icon: string = '';
  @Prop color: string = '#007AFF';
  @Prop trend: string = '';
}
  1. 根据趋势值显示不同颜色的趋势标签:
if (this.trend) {
  Text(this.trend)
    .fontSize(10)
    .fontColor(this.trend.startsWith('+') ? '#34C759' : '#FF3B30')
    .backgroundColor(this.trend.startsWith('+') ? '#E8F5E9' : '#FFEBEE')
    .padding({ left: 4, right: 4, top: 2, bottom: 2 })
    .borderRadius(4)
}
  1. 使用图标背景色的透明度变体创建协调的视觉效果:
.backgroundColor(this.color + '15')
  1. 完整示例代码:
@Component
export struct StatCard {
  @Prop value: string = '0';
  @Prop label: string = '';
  @Prop icon: string = '';
  @Prop color: string = '#007AFF';
  @Prop trend: string = '';

  build() {
    Column({ space: 8 }) {
      if (this.icon) {
        Column() { Text(this.icon).fontSize(22) }
          .width(44).height(44).borderRadius(14)
          .backgroundColor(this.color + '15')
          .justifyContent(FlexAlign.Center)
      }
      Row({ space: 4 }) {
        Text(this.value).fontSize(26).fontWeight(FontWeight.Bold).fontColor('#333333')
        if (this.trend) {
          Text(this.trend)
            .fontSize(10)
            .fontColor(this.trend.startsWith('+') ? '#34C759' : '#FF3B30')
            .backgroundColor(this.trend.startsWith('+') ? '#E8F5E9' : '#FFEBEE')
            .padding({ left: 4, right: 4, top: 2, bottom: 2 })
            .borderRadius(4)
        }
      }
      Text(this.label).fontSize(13).fontColor('#999999')
    }
    .padding(16)
    .backgroundColor('#FFFFFF')
    .borderRadius(16)
    .shadow({ radius: 8, color: 'rgba(0,0,0,0.05)', offsetX: 0, offsetY: 2 })
  }
}

@Entry
@Component
struct StatCardDemo {
  build() {
    Row({ space: 12 }) {
      StatCard({ value: '128', label: '已学习', icon: '📚', color: '#007AFF', trend: '+12%' }).layoutWeight(1)
      StatCard({ value: '86%', label: '正确率', icon: '✅', color: '#34C759', trend: '+5%' }).layoutWeight(1)
    }
    .padding(16)
  }
}

更多关于HarmonyOS鸿蒙Next中如何实现统计数字卡片组件?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS Next中,统计数字卡片组件可通过ArkUI的声明式UI开发。使用Column、Row等布局容器组合,配合Text组件展示数字与标签。数字部分通常用Text设置大字体样式,标签用较小字体。可结合Counter组件实现数字动态变化效果,或通过数据绑定更新显示内容。样式自定义通过属性方法设置颜色、圆角等。

在HarmonyOS Next中,可以通过ArkUI的声明式语法高效构建统计数字卡片组件。核心是使用FlexRowColumnTextImage等基础组件进行组合布局,并利用@State等装饰器实现数据驱动更新。

1. 组件结构设计 建议将卡片拆分为以下部分,使用Column作为根容器:

  • 顶部区域(可选)Row布局,包含图标与主标题。
  • 中部核心区域RowColumn布局,展示核心数值与趋势指示器(图标+百分比)。
  • 底部标签区域Text组件显示描述性标签。
  • 卡片容器:使用FlexStack,设置圆角、阴影、背景色等样式。

2. 关键实现代码示例

@Component
export struct StatsCard {
  // 使用装饰器管理数据
  @State value: number = 0
  @State trend: number = 0 // 正负百分比
  @State label: string = ''
  @State icon: Resource = $r('app.media.icon')

  build() {
    Column({ space: 12 }) {
      // 顶部图标与标题
      Row({ space: 8 }) {
        Image(this.icon)
          .width(24)
          .height(24)
        Text('统计指标')
          .fontSize(16)
          .fontWeight(FontWeight.Medium)
      }

      // 核心数值与趋势
      Row({ space: 8 }) {
        Text(this.value.toFixed(0))
          .fontSize(32)
          .fontWeight(FontWeight.Bold)
        
        // 趋势指示器
        Row({ space: 4 }) {
          Image(this.trend >= 0 ? $r('app.media.arrow_up') : $r('app.media.arrow_down'))
            .width(16)
            .height(16)
          Text(`${Math.abs(this.trend)}%`)
            .fontSize(14)
            .fontColor(this.trend >= 0 ? '#0A8000' : '#D70000')
        }
        .padding({ left: 8, right: 8, top: 4, bottom: 4 })
        .backgroundColor(this.trend >= 0 ? '#E6F4EA' : '#FFEBE9')
        .borderRadius(12)
      }

      // 底部标签
      Text(this.label)
        .fontSize(14)
        .fontColor('#666')
    }
    .padding(24)
    .backgroundColor(Color.White)
    .borderRadius(24)
    .shadow({ radius: 16, color: '#1A000000', offsetX: 0, offsetY: 4 })
  }
}

3. 数据绑定与更新 在父组件中传递或动态更新数据:

@Entry
@Component
struct ParentComponent {
  @State cardData: StatsCardData = new StatsCardData()

  build() {
    Column() {
      StatsCard({
        value: this.cardData.value,
        trend: this.cardData.trend,
        label: this.cardData.label,
        icon: $r('app.media.chart_icon')
      })
      
      Button('更新数据')
        .onClick(() => {
          // 更新@State变量,触发UI自动刷新
          this.cardData.value = 1500
          this.cardData.trend = 12.5
        })
    }
  }
}

4. 样式定制建议

  • 使用@Styles@Extend提取通用样式
  • 通过@Prop参数化颜色、圆角等视觉属性
  • 响应式布局可结合mediaQuery适配不同屏幕

此方案充分利用ArkUI的声明式特性,数据变更自动触发UI更新,代码结构清晰且易于维护。

回到顶部