HarmonyOS6 - 运动健身三环展示图页面案例

HarmonyOS6 - 运动健身三环展示图页面案例

1. 页面效果

本示例是基于Progress组件构建三个环形进度条,实时显示运动数据,包括活动热量、锻炼时长、活动小时数三项数据。

2. 思路分析

  1. 这里实现圆环效果的话,需要使用 Progress 组件
  2. 需要设置三个 Progress 组件,并且type需要设置为:ProgressType.Ring
  3. 要用层叠效果需要使用Stack布局,将三个环形进度条中心对齐
  4. 必须要设置进度条的宽度strokeWidth和半径width,实现半径等差的三个同心圆效果
  5. 然后再分别设置每个进度条的背景颜色backgroundColor和运动数据颜色color
  6. 为了有动态效果,新增一个按钮,绑定onClick点击事件,使用setInterval做数据的更新操作
  7. 最后使用offset设置小图标的位置偏移量即可

3. 代码编写

页面代码如下:

js 复制代码
@Entry
@Component
struct Test001 {
  @State stepNumber: number = 1713;
  @State targetStepNumber: number = 20000;
  @State exerciseCalories: number = 81;
  @State targetCalories: number = 290;
  @State exerciseTime: number = 27;
  @State targetTime: number = 80;
  @State totalTime: number = 6;
  @State targetTotalTime: number = 14;

  //分割线
  @Builder
  MyDivider() {
    Divider()
      .strokeWidth(1)
      .color('#cccccc')
      .width('100%')
      .margin({ left: 65 });
  }

  build() {
    Column({ space: 8 }) {
      Row() {
        Text('运动记录')
          .fontSize(20)
          .fontWeight(800)
          .margin({ left: 5 }) //设置外边距
      }
      .width('100%')
      .margin({ top: 5, bottom: 5 }) //设置外边距
      .justifyContent(FlexAlign.Start) //设置对齐方式

      Column() {
        Row() {
          Image($r('app.media.steps'))
            .height(24);
          Text(this.stepNumber.toString())
            .margin({ left: 20 });
          Text(' / ');
          Text(this.targetStepNumber.toString() + '步')
            .fontColor(Color.Gray);
        }
        .width('100%')
        .justifyContent(FlexAlign.Start) //设置主轴方向对齐方式
        .alignItems(VerticalAlign.Center); //设置交叉轴对齐方式

        //圆环层叠布局
        Stack({ alignContent: Alignment.Center }) {
          Progress({ value: this.totalTime, total: this.targetTotalTime, type: ProgressType.Ring })
            .width(100)
            .color('#ff3e812c')//设置圆环颜色
            .style({ strokeWidth: 18, shadow: true })//设置圆环宽度
            .backgroundColor('#d5e5ff'); //设置圆环背景色
          Image($r('app.media.hours'))
            .height(12)
            .offset({ x: 3, y: -30 }) //设置位置偏移量

          Progress({ value: this.exerciseTime, total: this.targetTime, type: ProgressType.Ring })
            .width(150)
            .color('#ff11dd6c')
            .style({ strokeWidth: 18, shadow: true })
            .backgroundColor('#feefcd');
          Image($r('app.media.times'))
            .height(12)
            .offset({ x: 3, y: -55 });

          Progress({ value: this.exerciseCalories, total: this.targetCalories, type: ProgressType.Ring })
            .width(200)
            .color('#ffff0000')
            .style({ strokeWidth: 18, shadow: true })
            .backgroundColor('#fbd4d3');
          Image($r('app.media.calories'))
            .height(12)
            .offset({ x: 3, y: -80 });
        }
        .padding({ top: 20 });

        // 活动热量数据
        Row() {
          Row() {
            Image($r('app.media.calories'))
              .height(20);
          }
          .height(34)
          .width(34)
          .backgroundColor('#ffff0000')
          .justifyContent(FlexAlign.Center)
          .alignItems(VerticalAlign.Center)
          .borderRadius(8) //设置圆角效果

          Column() {
            Text($r('app.string.activity_heat'))
              .fontSize(18)
              .fontWeight(450) //设置加粗效果
            Row() {
              Text(this.exerciseCalories.toString())
                .fontSize(34);
              Text(' /' + this.targetCalories.toString() + '千卡')
                .fontColor(Color.Gray);
            }
            .alignItems(VerticalAlign.Bottom);
          }
          .alignItems(HorizontalAlign.Start)
          .margin({ left: 20 });
        }
        .width('100%')
        .margin({ top: 20, bottom: 18 });

        //设置分割线
        this.MyDivider()

        // 锻炼时长数据
        Row() {
          Row() {
            Image($r('app.media.times'))
              .height(20);
          }
          .height(34)
          .width(34)
          .backgroundColor('#ff11dd6c')
          .justifyContent(FlexAlign.Center)
          .alignItems(VerticalAlign.Center)
          .borderRadius(8);

          Column() {
            Text($r('app.string.exercise_duration'))
              .fontSize(18)
              .fontWeight(450);
            Row() {
              Text(this.exerciseTime.toString())
                .fontSize(34);
              Text(' /' + this.targetTime.toString() + '分钟')
                .fontColor(Color.Gray);
            }
            .alignItems(VerticalAlign.Bottom);
          }
          .alignItems(HorizontalAlign.Start)
          .margin({ left: 20 });
        }
        .width('100%')
        .margin({ top: 18, bottom: 18 });

        //设置分割线
        this.MyDivider()

        // 活动小时数数据
        Row() {
          Row() {
            Image($r('app.media.hours'))
              .height(20);
          }
          .height(34)
          .width(34)
          .backgroundColor('#ff3e812c')
          .justifyContent(FlexAlign.Center)
          .alignItems(VerticalAlign.Center)
          .borderRadius(8);


          Column() {
            Text($r('app.string.activity_hours'))
              .fontSize(18)
              .fontWeight(450);
            Row() {
              Text(this.totalTime.toFixed(1))
                .fontSize(34);
              Text(' /' + this.targetTotalTime.toString() + '小时')
                .fontColor(Color.Gray);
            }
            .alignItems(VerticalAlign.Bottom);
          }
          .alignItems(HorizontalAlign.Start)
          .margin({ left: 20 });
        }
        .width('100%')
        .margin({ top: 18 });
      }
      .backgroundColor(Color.White)
      .borderRadius(16)
      .padding(18);

      Button($r('app.string.start_exercising'))
        .borderRadius(5)
        .onClick(() => {
          setInterval(() => {
            this.exerciseCalories += 10;
            this.exerciseTime += 1;
            this.totalTime += 0.3;
            this.stepNumber += 12;
          }, 1000);
        })
    }
    .width('100%')
    .height('100%')
    //设置左右的内边距
    .padding({
      left: 10,
      right: 10,
    })
    .backgroundColor('#f0f2f5');
  }
}

注意:代码中涉及到的一些小图标大家自己下载好了放到media目录中即可

相关推荐
ShuiShenHuoLe34 分钟前
管理数据的状态
harmonyos·鸿蒙
坚果派·白晓明2 天前
三方库ada
harmonyos·鸿蒙·openharmony
云和数据.ChenGuang2 天前
鸿蒙餐饮系统:全场景智慧餐饮新范式
人工智能·机器学习·华为·数据挖掘·harmonyos·鸿蒙·鸿蒙系统
云和数据.ChenGuang3 天前
鸿蒙智联,极智共生:HarmonyOS与MiniMax智能体的融合新纪元
华为·harmonyos·鸿蒙
UnicornDev3 天前
【HarmonyOS 6】今日统计卡片实战:运动记录数据概览
华为·harmonyos·arkts·鸿蒙·鸿蒙系统
ShuiShenHuoLe3 天前
组件的状态ComponentV2
harmonyos·鸿蒙
是稻香啊3 天前
HarmonyOS6 ArkTS Popup 气泡组件指南
harmonyos6
是稻香啊4 天前
HarmonyOS6 触摸目标 touch-target 属性使用指南
harmonyos6
仓颉编程语言4 天前
CangjieSkills 正式开源:为仓颉 AI 编程打造的“技能增强“方案,实测降低 60% 费用
华为·ai编程·鸿蒙·仓颉编程语言
左手厨刀右手茼蒿5 天前
Flutter 三方库 all_lint_rules_community 的鸿蒙化适配指南 - 在鸿蒙系统上构建极致、严谨、基于全量社区 Lint 规则的工业级静态代码质量与安全审计引擎
flutter·harmonyos·鸿蒙·openharmony·all_lint_rules_community