鸿蒙实战案例-饮食记录-统计卡片


前言

本文将介绍如何使用HarmonyOS的ArkTS语言编写一个健康app中的统计数据卡片功能。该功能主要包括日期选择、热量统计和营养素统计三个部分。通过直观的界面展示,帮助用户了解自己的热量和营养素摄入情况,从而更好地管理自己的饮食和运动。


一、饮食记录UI设计分析

二、各组件的详细及联系

一、StatsCard

先定义了一个名为StatsCard的组件,主要用于展示健康app中的统计数据卡片功能。我们可以通过日期选择对话框选择一个特定的日期,默认为当前日期的开始时间。选定的日期将用于统计和展示该日的热量和营养素摄入情况。通过CalorieStats组件展示用户在选定日期的饮食摄入、还可以吃和运动消耗的热量数据。通过NutrientStats组件展示用户在选定日期的碳水化合物、蛋白质和脂肪等营养素的摄入量。

代码如下:

import { CommonConstants } from '../../common/constants/CommonConstants'
import DateUtil from '../../common/utils/DateUtil'
import CalorieStats from './CalorieStats'
import DatePickDialog from './DatePickDialog'
import NutrientStats from './NutrientStats'
@Component
export default  struct StatsCard {

  @StorageProp('selectedDate') selectedDate:number = DateUtil.beginTimeOfDay(new Date())

  controller:CustomDialogController = new CustomDialogController({
    builder:DatePickDialog({selectedDate:new Date(this.selectedDate)})
  })
  build() {
    Column(){
      //1.日期信息
      Row(){
        Text(DateUtil.formatDate(this.selectedDate))
          .fontColor($r('app.color.secondary_color'))
        Image($r('app.media.ic_public_spinner'))
          .width(20)
          .fillColor($r('app.color.secondary_color'))
      }
      .padding(CommonConstants.SPACE_8)
      .onClick(()=>this.controller.open())
      //2.统计信息
      Swiper(){
        // 2.1.热量统计
        CalorieStats()
        // 2.2.营养素统计
        NutrientStats()
      }
      .width('100%')
      .backgroundColor(Color.White)
      .borderRadius(CommonConstants.DEFAULT_18)
    }
    .width(CommonConstants.THOUSANDTH_940)
    .backgroundColor($r('app.color.stats_title_bgc'))
    .borderRadius(CommonConstants.DEFAULT_18)

  }
}

运行截图:

二、DatePickDialog

DatePickDialog 组件是一个日期选择对话框,主要功能是让用户可以选择一个特定的日期。使用DatePicker组件,我们可以选择一个日期范围从2020年1月1日到当前日期。DatePicker的start属性设置为2020年1月1日,end属性设置为当前日期,selected属性设置为this.selectedDate,即默认选中的日期为当前日期。当用户在DatePicker中选择了一个新的日期时,会触发一个事件,通过该事件可以获取用户选择的年份、月份和日期,并将这些值更新到this.selectedDate中。在底部提供一个取消按钮和一个确定按钮。点击取消后会关闭对话框但不保存任何更改。点击确定后会执行两个操作:首先,将选中的日期以毫秒形式保存到全局存储中,键为selectedDate。然后,关闭对话框。

代码如下:

import { CommonConstants } from '../../common/constants/CommonConstants'
@Preview
@CustomDialog
export default struct DatePickDialog {
  controller:CustomDialogController
  selectedDate:Date = new Date()
  build() {
    Column({space:CommonConstants.SPACE_12}){
      //1.日期选择器
      DatePicker({
        start: new Date('2020-01-01'),
        end: new Date(),
        selected: this.selectedDate
      })
        .onChange((value: DatePickerResult) => {
          this.selectedDate.setFullYear(value.year, value.month, value.day)
        })
      //2.按钮
      Row({space:CommonConstants.SPACE_12}){
        Button('取消')
          .width(120)
          .backgroundColor($r('app.color.light_gray'))
          .onClick(()=>this.controller.close())
        Button('确定')
          .width(120)
          .backgroundColor($r('app.color.primary_color'))
          .onClick(()=>{
            //1.保存日期到全局存储
            AppStorage.SetOrCreate('selectedDate',this.selectedDate.getTime())
            //2.关闭窗口
            this.controller.close()
          })
      }

    }
    .padding(CommonConstants.SPACE_12)
  }
}

运行截图:

三、CalorieStats

CalorieStats组件用于展示用户的饮食摄入、运动消耗和推荐摄入量等信息。定义了一个名为remainCalorie的方法,用于计算剩余卡路里(推荐摄入量减去饮食摄入加上运动消耗)。在build方法中,使用Row布局,将饮食摄入、还可以吃和运动消耗的信息展示在一个行内。在还可以吃的Stack中,使用Progress组件展示进度条,表示饮食摄入占推荐摄入量的比例。同时,使用StatsBuilder方法展示还可以吃的卡路里数量和推荐摄入量。使用StatsBuilder方法展示饮食摄入和运动消耗的信息。

代码如下:

import { CommonConstants } from '../../common/constants/CommonConstants'
@Component
export default struct CalorieStats {
   intake: number=192
   expend: number=150
  recommend: number = CommonConstants.RECOMMEND_CALORIE

  remainCalorie(){
    return this.recommend - this.intake + this.expend
  }

  build() {
    Row({space: CommonConstants.SPACE_6}){
      // 1.饮食摄入
      this.StatsBuilder({label: '饮食摄入', value: this.intake})
      // 2.还可以吃
      Stack(){
        // 2.1.进度条
        Progress({
          value: this.intake,
          total: this.recommend,
          type: ProgressType.Ring
        })
          .width(120)
          .style({strokeWidth: CommonConstants.DEFAULT_10})
          .color($r('app.color.primary_color'))
        // 2.2.统计数据
        this.StatsBuilder({label: '还可以吃', value: this.remainCalorie(),tips: `推荐${this.recommend}`})
      }
      // 3.运动消耗
      this.StatsBuilder({label: '运动消耗', value: this.expend})
    }
    .width('100%')
    .justifyContent(FlexAlign.SpaceEvenly)
    .padding({top: 30, bottom: 35})
  }

  @Builder StatsBuilder($$:{label: string, value: number, tips?: string}){
    Column({space: CommonConstants.SPACE_6}){
      Text($$.label)
        .fontColor($r('app.color.gray'))
        .fontWeight(CommonConstants.FONT_WEIGHT_600)
      Text($$.value.toFixed(0))
        .fontSize(20)
        .fontWeight(CommonConstants.FONT_WEIGHT_700)
      if($$.tips){
        Text($$.tips)
          .fontSize(12)
          .fontColor($r('app.color.light_gray'))
      }
    }
  }
}

运行截图:

四、NutrientStats

NutrientStats组件用于展示用户摄入的营养成分(碳水化合物、蛋白质和脂肪)以及推荐的摄入量。定义了三个属性:carbon(碳水化合物)、protein(蛋白质)和fat(脂肪),分别表示用户摄入的营养成分数量。同时,还定义了三个推荐摄入量的属性:recommendCarbon、recommendProtein和recommendFat。 build()方法用于构建组件的布局。在这个方法中,使用Row布局将三个营养成分(碳水化合物、蛋白质和脂肪)放在一行中,并设置间距。然后,为每个营养成分创建一个StatsBuilder实例,传入相应的标签、值、推荐值和颜色。最后,设置整个布局的宽度、对齐方式和内边距。StatsBuilder方法用于构建每个营养成分的展示部分。在这个方法中,首先创建一个Column布局,然后在其中创建一个Stack布局,用于放置环形进度条和两个文本。环形进度条的值为当前营养成分的摄入量,总值为推荐摄入量,类型为ProgressType.Ring。进度条的宽度、线宽和颜色由参数指定。接下来,创建两个文本,分别显示“摄入推荐”和当前摄入量与推荐摄入量的比例。最后,创建一个文本显示营养成分的名称,并设置字体大小和颜色。

代码如下:

import { CommonConstants } from '../../common/constants/CommonConstants'
@Component
export default struct NutrientStats {
   carbon: number=23
   protein: number=9
   fat: number=7

  recommendCarbon: number = CommonConstants.RECOMMEND_CARBON
  recommendProtein: number = CommonConstants.RECOMMEND_PROTEIN
  recommendFat: number = CommonConstants.RECOMMEND_FAT

  build() {
    Row({space: CommonConstants.SPACE_6}){
      this.StatsBuilder({
        label: '碳水化合物',
        value: this.carbon,
        recommend: this.recommendCarbon,
        color: $r('app.color.carbon_color')
      })
      this.StatsBuilder({
        label: '蛋白质',
        value: this.protein,
        recommend: this.recommendProtein,
        color: $r('app.color.protein_color')
      })
      this.StatsBuilder({
        label: '脂肪',
        value: this.fat,
        recommend: this.recommendFat,
        color: $r('app.color.fat_color')
      })
    }
    .width('100%')
    .justifyContent(FlexAlign.SpaceEvenly)
    .padding({top: 30, bottom: 35})
  }

  @Builder StatsBuilder($$:{label: string, value: number, recommend: number, color: ResourceStr}){
    Column({space: CommonConstants.SPACE_6}){
      Stack(){
        Progress({
          value: $$.value,
          total: $$.recommend,
          type: ProgressType.Ring
        })
          .width(95)
          .style({strokeWidth: CommonConstants.DEFAULT_6})
          .color($$.color)
        Column({space: CommonConstants.SPACE_6}){
          Text('摄入推荐')
            .fontSize(12)
            .fontColor($r('app.color.gray'))
          Text(`${$$.value.toFixed(0)}/${$$.recommend.toFixed(0)}`)
            .fontSize(18)
            .fontWeight(CommonConstants.FONT_WEIGHT_600)
        }
      }
      Text(`${$$.label}(克)`)
        .fontSize(12)
        .fontColor($r('app.color.light_gray'))
    }
  }
}

运行截图:


总结

通过本文的介绍,我们详细分析了该统计卡片组件的设计和实现细节,包括日期选择、热量统计和营养素统计等功能。StatsCard主要包含了三个组件:DatePickDialog,CalorieStats和NutrientStats。StatsCard为统计卡片的主组件,包含日期选择、热量统计和营养素统计,通过DatePickDialog组件来选择日期,并在界面上显示所选日期;通过CalorieStats组件来展示用户的饮食摄入、还可以吃和运动消耗的热量统计;通过NutrientStats来展示用户摄入的碳水化合物、蛋白质和脂肪的统计数据。

  • 24
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值