开发鸿蒙项目黑马健康APP统计卡片

  一、工作的主要介绍

今天的任务主要是完成饮食记录中的饮食卡片;这一部分用到了新的内容日期选择窗,穿梭切换的组件。

二、运行效果及主要设计思路的介绍

1.饮食记录中的饮食卡片的运行截图

2.饮食记录中的饮食卡片的思路

饮食记录中的饮食卡片首先根据页面的布局,这一部分也是从上到下的列式布局,首先就是写日期的弹窗的问题,然后就是实现饮食卡片的问题,和可以滑动的切换写一个营养素的卡片,然后使用进度条使这个卡片更加美观。

三、在设计的过程中遇到的问题

1.日期选择器的使用

设置一个selectedDate来定义一个日期为现在的时间,然后在DatePicker中有开始时间、结束时间。

2.日期怎么能够做的到全局都能看到

要把日期保存到全局存储,用APPStorage中SetOrCreate,在后面把当前日期的毫秒值储存进去。

四、最终实验代码

1.饮食记录中的饮食卡片代码

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 CaloriesStats from './CaloriesStats'
import DatePickDialog from './DatePickDialog'
import NutrientStats from './NutrientStats'
@Preview
@Component
export default struct StatsCard {
  @StorageProp('selected') selectedDate:number = DateUtil.beginTimeOfDay(new Date())
  @StorageProp('currentBreakpoint') currentBreakpoint: string = BreakpointConstants.BREAKPOINT_SM

  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.热量消耗
        CaloriesStats()
        //2.2营养素统计
        NutrientStats()
      }
      .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 CaloriesStats {
  intake:number = 192
  expend:number = 150
  recommend: number = CommonConstants.RECOMMEND_CALORIE
  remainCalorie(){
    return this.recommend-this.intake+this.expend
  }

  build() {
    Row(){
      //1.饮食摄入
     this.StatsBuilder('饮食摄入',this.intake)
      //2.还可以吃
      Stack(){
        Progress({
          value : this.intake,
          total : this.recommend,
          type:ProgressType.Ring
        })
          .width(120)
          .style({strokeWidth:CommonConstants.DEFAULT_10})
          .color($r('app.color.primary_color'))
        this.StatsBuilder('还可以吃',this.remainCalorie(),`推荐${this.recommend}`)
      }

      //3.运动消耗
      this.StatsBuilder('运动消耗',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'))
      }

    }
  }
}



import { CommonConstants } from '../../common/constants/CommonConstants'
@CustomDialog
export default struct DatePickDialog {
  //弹窗
  controller : CustomDialogController
  selectedDate:Date = new Date()
  build() {
   Column(){
     //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(){
       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('selected',this.selectedDate.getTime())
           //2.关闭窗口
           this.controller.close()
         })
     }

   }
    .padding(CommonConstants.SPACE_12)
  }
}


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(){
      //1.饮食摄入
      this.StatsBuilder('碳水化合物',this.carbon,this.recommendCarbon,$r('app.color.carbon_color'))
      //2.还可以吃
     this.StatsBuilder('蛋白质',this.protein,this.recommendProtein,$r('app.color.protein_color'))
      //3.运动消耗
      this.StatsBuilder('脂肪',this.fat,this.recommendFat,$r('app.color.fat_color'))
    }
    .width('100%')
    .justifyContent(FlexAlign.SpaceEvenly)
    .padding({top:30,bottom:35})
  }
  @Builder StatsBuilder( label:string,value:number,recommend:number,color:Resource){
    Column({ space: CommonConstants.SPACE_6 }) {
      Stack(){
        Progress({
          value : value,
          total : recommend,
          type:ProgressType.Ring
        })
          .width(95)
          .style({strokeWidth:CommonConstants.DEFAULT_6})
          .color(color)

       Column(){
         Text('摄入推荐')
           .fontSize(12)
           .fontColor($r('app.color.light_gray'))
           .fontWeight(CommonConstants.FONT_WEIGHT_600)
         Text(`${value.toFixed(0)}/${recommend.toFixed(0)}`)
           .fontSize(20)
           .fontWeight(CommonConstants.FONT_WEIGHT_700)
       }
      }
      Text(`${label}(克)`)
        .fontSize(12)
        .fontColor($r('app.color.light_gray'))


    }
  }
}

五、总结

1.组件化和模块化设计

代码中定义了多个结构化组件,每个组件负责显示应用中的一个特定部分。这种组件化的方法有助于代码的组织和复用,使得维护和更新变得更加容易。例如,CaloriesStatsNutrientStats分别处理热量和营养素的统计显示,而DatePickDialog提供了一个自定义的日期选择器对话框。

2.使用存储和状态管理

组件使用@StorageProp装饰器来存储和检索用户的选择,通过@StorageProp来持久化的。

3.自定义UI元素和交互

使用自定义UI元素和交互模式,Swiper用于在热量消耗和营养素统计之间滑动切换,Progress组件用于显示进度环,以及Stack用于堆叠布局。此外,DatePickDialog中的DatePicker组件允许用户选择日期,并通过按钮进行确认或取消操作。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值