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

相关推荐
星释5 小时前
鸿蒙Flutter实战:29.优先使用联合插件开发鸿蒙化插件
flutter·华为·harmonyos·鸿蒙
加农炮手Jinx11 小时前
Flutter 三方库 better_commit 的鸿蒙化适配指南 - 实现具备语义化提交规范与自动化交互的 Git 工作流插件、支持端侧版本工程的高效规范化审计实战
flutter·harmonyos·鸿蒙·openharmony·better_commit
2301_822703201 天前
渐变壁纸生成:基于鸿蒙Flutter的跨平台壁纸创建工具
flutter·华为·harmonyos·鸿蒙
人间打气筒(Ada)1 天前
「码动四季·开源同行」HarmonyOS应用开发:常见组件
华为·开源·harmonyos·组件·布局·鸿蒙开发
2301_822703201 天前
开源鸿蒙跨平台Flutter开发:幼儿疫苗全生命周期追踪系统:基于 Flutter 的免疫接种档案与状态机设计
算法·flutter·华为·开源·harmonyos·鸿蒙
2301_822703201 天前
鸿蒙flutter三方库实战——教育与学习平台:Flutter Markdown
学习·算法·flutter·华为·harmonyos·鸿蒙
2301_822703201 天前
开源鸿蒙跨平台Flutter开发:蛋白质序列特征提取:氨基酸组成与理化性质计算
flutter·华为·开源·harmonyos·鸿蒙
钛态1 天前
Flutter 三方库 ethereum_addresses 的鸿蒙化适配指南 - 掌控区块链地址资产、精密校验治理实战、鸿蒙级 Web3 专家
flutter·harmonyos·鸿蒙·openharmony·ethereum_addresses
Industio_触觉智能1 天前
触觉智能Purple Pi OH开发板已适配OpenHarmony6.1,将作为LTS长期支持版,附API参考说明
鸿蒙·鸿蒙系统·openharmony·lts·开源鸿蒙·鸿蒙开发板·openharmony6.1
2301_822703201 天前
鸿蒙Flutter三方库适配:Flutter Markdown适配实战-鸿蒙平台的Markdown渲染解决方案
flutter·华为·信息可视化·开源·harmonyos·鸿蒙·三方库