黑马健康——饮食记录—统计卡片

 一,前言

        综合运用本学期所学内容及个人自学知识,使用HarmonyOS 4.0及以上版本开发一款具有实用性和创新性的移动应用软件。

二.应用界面UI

(1)页面UI分析

(2)代码

 import BreakpointType from '../../common/bean/BreanpointType'
import BreakpointConstants from '../../common/constants/BreakpointConstants'
import { CommonConstants } from '../../common/constants/CommonConstants'
import DateUtil from '../../common/utils/DateUtil'
import RecordService from '../../service/RecordService'
import RecordVO from '../../viewmodel/RecordVO'
import StatsInfo from '../../viewmodel/StatsInfo'
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())
  @StorageProp('currentBreakpoint') currentBreakpoint: string = BreakpointConstants.BREAKPOINT_SM

  @Consume @Watch('handleRecordsChange') records: RecordVO[]
  @State info: StatsInfo = new StatsInfo()

  handleRecordsChange(){
    this.info = RecordService.calculateStatsInfo(this.records)
  }

  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({intake: this.info.intake, expend: this.info.expend})
        // 2.2.营养素统计
        NutrientStats({carbon: this.info.carbon, protein: this.info.protein, fat: this.info.fat})
      }
      .width('100%')
      .backgroundColor(Color.White)
      .borderRadius(CommonConstants.DEFAULT_18)
      .indicatorStyle({selectedColor: $r('app.color.primary_color')})
      .displayCount(new BreakpointType({
        sm: 1,
        md: 1,
        lg: 2
      }).getValue(this.currentBreakpoint))
    }
    .width(CommonConstants.THOUSANDTH_940)
    .backgroundColor($r('app.color.stats_title_bgc'))
    .borderRadius(CommonConstants.DEFAULT_18)
  }
}


import { CommonConstants } from '../../common/constants/CommonConstants'
@Component
export default struct CalorieStats {
  @Prop intake: number
  @Prop expend: number
  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'))
      }
    }
  }
}

 (3)运行效果截图

三.总结

         这段代码片段展示了一个Vue.js组件(`StatsCard`)的结构,该组件使用了一种假设的框架或库,该框架或库采用了类似Vue的组合API的语法,并包含了一些自定义装饰器(如`@Component`、`@StorageProp`、`@Consume`、`@Watch`)。这个组件主要用于展示统计数据,包括热量和营养素的统计,并且能够响应不同断点下的布局变化以及与日期选择对话框进行交互。下面是该代码段的详细解析:

组件定义与状态管理:

  `@Component`装饰器标志着这是一个Vue组件。

  `@StorageProp`装饰器用于从存储中读取和写入数据,这里分别用于`selectedDate`(选定的日期,默认为当前日期的开始时间)和`currentBreakpoint`(当前屏幕断点,默认为小型屏幕)。

  `@Consume`装饰器可能暗示着该组件通过某种方式(例如 Vuex 状态管理)消费外部状态,这里是一个名为`records`的记录列表。

  `@State`装饰器定义了组件内的响应式状态,这里是`info`,一个保存统计信息的对象实例。

方法定义:

  `handleRecordsChange`方法会在`records`变更时被自动调用(由`@Watch`装饰器监听),用于根据最新的记录数据重新计算统计信息。

对话框控制器:

  `controller`变量初始化了一个`CustomDialogController`,用于控制日期选择对话框的显示。它使用了`DatePickDialog`组件,并传入了初始选中的日期。

构建UI结构:

  `build`方法内部使用了类似Vue模板的语法来构建组件的UI布局。主要包括日期显示行(点击可打开日期选择对话框)、以及一个Swiper组件来切换显示不同的统计信息(热量统计`CalorieStats`和营养素统计`NutrientStats`)。

  Swiper的显示数量会根据当前屏幕断点动态调整,这是通过一个自定义的`BreakpointType`类实现的,它根据给定的断点(如sm、md、lg)返回相应的值。

样式与布局:

  代码中使用了多个自定义常量(如`CommonConstants.SPACE_8`、`CommonConstants.DEFAULT_18`)和颜色资源(如`$r('app.color.secondary_color')`)来统一管理样式和布局,这有助于保持设计的一致性并方便后期维护。

综上所述,`StatsCard`组件旨在提供一个交互式的统计数据展示界面,用户可以通过点击日期区域选择不同的日期来查看相应日期的统计信息,同时组件能够自适应不同屏幕尺寸,展示适宜数量的统计卡片。

这段代码定义了一个Vue组件`CalorieStats`,其主要功能是展示和计算与热量摄入和消耗相关的统计数据。以下是该组件的详细说明:

 导入与组件定义:

   首先,从`CommonConstants`模块导入了一些通用常量,用于设置默认值和样式。

   使用`@Component`装饰器定义了`CalorieStats`组件。

   组件接收两个Props(属性):`intake`(饮食摄入的热量)和`expend`(运动消耗的热量),并定义了一个内部变量`recommend`,其值为`CommonConstants.RECOMMEND_CALORIE`,即推荐的日热量摄入值。

 计算剩余热量:

   定义了一个方法`remainCalorie`,用于计算基于推荐摄入值、实际摄入值和消耗值的剩余可摄入热量。

 UI构建方法 (`build`):

   使用自定义的布局方法构建组件的UI,包括三个部分:饮食摄入、一个结合进度条显示的“还可以吃”统计,以及运动消耗。

   在构建UI时,应用了间距、对齐方式、宽度等样式,并通过条件渲染展示了额外的提示信息(如推荐热量摄入值)。

 自定义构建器方法 (`StatsBuilder`):

   定义了一个内部方法`StatsBuilder`作为构建器函数,接受一个对象参数`$$`,用于创建包含标签、数值及可选提示的统计项展示。

   这个方法内部使用了Column布局,以一定的间距组织文本内容,包括不同样式的字体颜色、大小和权重,以清晰地展示各项统计信息。

综上所述,`CalorieStats`组件负责展示用户的热量摄入与消耗情况,包括一个直观的进度条展示剩余可摄入热量相对于推荐值的比例,以及通过`StatsBuilder`灵活构建各项统计详情,提升了用户体验和界面的可维护性。

  • 37
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值