鸿蒙开发案例:健康App(5)饮食记录-统计卡片

 系列文章目录

鸿蒙开发案例:健康App(1)欢迎页面Ul实现

                         健康App(2)欢迎页面业务

                         健康App(3)首页Tabs

                         健康App(4)饮食记录-顶部搜索栏 

                         健康App(5)饮食记录-统计卡片

                         健康App(6)饮食记录-记录列表


前言

案例来源于黑马程序员的课程


案例介绍

饮食记录-统计卡片

一、整体思路

二、实现步骤

1.日期信息

日期信息样式

颜色比主色调更深一点

记得在DatePickDialog.ets中使用

弹窗组件:日期选择器,按钮

日期选择器:在API中查找,复制并修改

按钮:取消灰色,确定主色调(绿色)按钮之间加一点距离

点击取消:close

点击确定:

1)存毫秒值(全局存储)

2)关闭窗口

 在StatsCard中运用:

beginTimeOfDay获取今天的开始日期

读取,回显,产生联动效果

修改日期信息

添加点击事件:打开弹窗

2.统计信息

可滑动对话框Swiper(API)

现在背景还是蓝色,将文字背景色去掉即可

3.热量组件

 

现在代码重复率很高,参照“还可以吃”进行抽取(Builder函数)

进度条(Stack)

4.营养素组件

和热量组件类似


总结 

// src/main/ets/view/record/StatsCard.ets

import DateUtil from '../../common/utils/DateUtil'
import DatePickDialog from './DatePickDialog'
import { CommonConstants } from '../../common/constants/CommonConstants'
import CalorieStats from './CalorieStats'
import NutrientStats from './NutrientStats'

@Component
export default struct StatsCard {
  // 把selectedDate从AppStorage里出去来,这里需要用到 @StorageProp这个注解,同时我们要对取出来的日期处理,因为我们存的是日期毫秒数,这里自己写了个工具类
  @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)
      .indicatorStyle({selectedColor: $r('app.color.primary_color')})
    }
    .width(CommonConstants.THOUSANDTH_940)
    .backgroundColor($r('app.color.stats_title_bgc'))
    .borderRadius(CommonConstants.DEFAULT_18)
  }
}
// src/main/ets/view/record/DatePickDialog.ets

import { CommonConstants } from '../../common/constants/CommonConstants'

// 定义日期弹窗
@CustomDialog
export default struct DatePickDialog {
  controller: CustomDialogController
  selectedDate: Date = new Date()
  build() {
    Column({space: CommonConstants.SPACE_12}){
      // 1.日期选择器,DatePicker官方组件
      DatePicker({
        start: new Date('2020-01-01'),
        end: new Date(),
        selected: this.selectedDate
      })
        .onChange((value: DatePickerResult) => {
          // 注意这里,选择的结果是年月日,没有时分秒,默认是当日的0时,0分,0秒
          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是一个全局的存储空间,getTime()获取的是日期毫秒数,以为存一个日期对象,会不好处理
            AppStorage.SetOrCreate('selectedDate', this.selectedDate.getTime())
            // 2.关闭窗口
            this.controller.close()
          })

      }

    }
    .padding(CommonConstants.SPACE_12)
  }
}
// src/main/ets/view/record/CalorieStats.ets
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('饮食摄入', 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('还可以吃', 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'))
      }
    }
  }
}
// src/main/ets/view/record/NutrientStats.ets

import { CommonConstants } from '../../common/constants/CommonConstants'
@Component
export default struct NutrientStats {
  // 碳水化合物
  carbon: number = 10
  // 蛋白质
  protein: number = 20
  // 脂肪
  fat: number  = 20

  // 推荐摄入的碳水化合物,蛋白质,脂肪
  recommendCarbon: number = CommonConstants.RECOMMEND_CARBON
  recommendProtein: number = CommonConstants.RECOMMEND_PROTEIN
  recommendFat: number = CommonConstants.RECOMMEND_FAT


  build() {
    Row({space: CommonConstants.SPACE_6}){
      this.StatsBuilder(
        '碳水化合物',
        this.carbon,
        this.recommendCarbon,
        $r('app.color.carbon_color')
      )

      this.StatsBuilder(
        '蛋白质',
        this.protein,
        this.recommendProtein,
        $r('app.color.protein_color')
      )
      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: 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'))
    }
  }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值