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目录中即可

相关推荐
世人万千丶2 天前
桌面便签小应用 - HarmonyOS ArkUI 开发实战-TextArea与Flex布局-PC版本
华为·harmonyos·鸿蒙·鸿蒙系统
YM52e2 天前
买菜计算器小应用 - HarmonyOS ArkUI 开发实战-PC版本
学习·华为·harmonyos·鸿蒙·鸿蒙系统
小雨下雨的雨2 天前
HarmonyOS ArkUI训练营入门-组件掌握系列-Animation 动画效果实现-PC版本
学习·华为·harmonyos·鸿蒙
三声三视2 天前
Electron 在鸿蒙 PC 上跑 webview,我是怎么把首屏从 4.2s 干到 1.1s 的
华为·electron·harmonyos·鸿蒙
世人万千丶2 天前
成语接龙小应用 - HarmonyOS ArkUI 开发实战-TextInput与List列表-PC版本
华为·list·harmonyos·鸿蒙·鸿蒙系统
TrisighT2 天前
AI写鸿蒙UI:10个跑崩8个,剩下2个看运气
ai编程·harmonyos·arkts
Davina_yu2 天前
自定义弹窗:使用CustomDialogController实现复杂交互(27)
harmonyos·鸿蒙·鸿蒙系统
世人万千丶2 天前
家庭记账本小应用 - HarmonyOS ArkUI 开发实战-Tabs与List组件-PC版本
华为·list·harmonyos·鸿蒙
至乐活着2 天前
HarmonyOS开发深度解析:网络请求与数据持久化实战全攻略
网络请求·harmonyos·arkts·数据持久化·鸿蒙开发
Davina_yu2 天前
画布Canvas:2D绘图上下文(Context2D)绘制复杂图表(33)
harmonyos·鸿蒙·鸿蒙系统