黑马健康应用开发(四)

一、饮食记录-统计卡片实现思路:

1.RecordIndex记录主页:

展示记录信息。该页面使用了Column容器来垂直排列页面的内容,将头部搜索栏SearchHeader()统计卡StatsCard()和记录列表 RecordList()导入。

2.StatsCard统计卡片:展示卡片信息。该页面使用了Column容器来垂直排列页面的内容,日期选择器,首先要设置一个装饰器属性,用于存储当前选中的日期初始化一个控制器,用于控制打开和关闭。使用 Swiper 容器构建可滑动的统计信息卡片,将热量统计和营养素统计进行切换。

3. CalorieStats 和NutrientStat热量统计卡片和营养素统计卡片:

使用Row容器进行水平布局。要构建了三个主要部分:
饮食摄入:通过方法构建了一个展示饮食摄入量和标签的列。
还可以吃:使用了容器来层叠显示一个环形进度条和统计数据。环形进度条显示了当前摄入热量占推荐值的比例,而统计数据则显示了剩余可摄入的热量和推荐摄入值。
运动消耗:同样通过方法构建了一个展示运动消耗量和标签的列。定义常量来设置间距、字体粗细、颜色等样式属性。Row容器使用方法来使子元素在水平方向上均匀分布。为环形进度条设置了宽度、环的粗细和颜色等样式。统计数据的字体大小和颜色。

NutrientStat的设计与CalorieStats相似,使用 Row 容器进行水平布局,设置子元素之间的间距。
定义了三个属性代表碳水化合物的摄入量、蛋白质的摄入量和脂肪的摄入量。
同时定义了三个推荐值属性这些值从 CommonConstants 导入。
构建三个主要部分,分别对应碳水化合物、蛋白质和脂肪的营养摄入情况。
营养摄入展示:对于每种营养物质,使用方法来构建一个包含环形进度条和统计数据的列(Column)容器。环形进度条通过 Progress 组件实现,用于展示当前摄入量占推荐值的比例。进度条的宽度、环的粗细和颜色都是可配置的。在环形进度条下方,有一个包含两行文本的列容器。第一行显示“摄入推荐”的提示信息,第二行显示具体的摄入量和推荐值。

4.DatePickDialog日期选择器:

使用 Column 容器进行垂直布局,并通过 space 属性设置子元素之间的间距。
创建一个组件,用于选择日期。设置起始日期,结束日期(end)为当前日期。
为组件添加事件监听器,当日期改变时,更新对象的值。
使用 Row 容器将两个按钮(取消和确定)水平排列,并通过属性设置它们之间的间距。
创建“取消”按钮,设置宽度、背景颜色和点击事件。点击事件关闭对话框。
创建“确定”按钮,同样设置宽度和背景颜色。点击事件首先调用方法,将选择的日期(转换为时间戳)保存到全局存储中,然后调用关闭对话框。

二、记录主页设计:

按照实现思路:

使用Column组件垂直排列。
设置Column容器的宽度和高度为100%,确保它占据整个页面的空间。
设置背景颜色为应用中的index_page_background颜色。
头部搜索栏:
导入SearchHeader组件,并在Column容器的顶部添加它。
统计卡:
导入StatsCard组件,并在SearchHeader组件下方添加它。
StatsCard组件用于展示一些统计信息。
记录列表:
导入RecordList组件,并在StatsCard组件下方添加它。
设置RecordList的layoutWeight为1,它将占据大部分剩余的垂直空间
 

import RecordList from './RecordList'
import SearchHeader from './SearchHeader'
import StatsCard from'./StatsCard'
@Component
@Preview
export default struct RecordIndex {
  build() {
    Column(){
      // 1.头部搜索栏
      SearchHeader()
      // 2.统计卡
      StatsCard()
      // 3.记录列表
      RecordList()
        .layoutWeight(1)
    }
    .width('100%')
    .height('100%')
    .backgroundColor($r('app.color.index_page_background'))
  }
}

三、记录卡片设计:

按照实现思路:

在record文件夹下新建StatsCard.ets文件

使用column组件,设置占屏幕的94%

日期信息,设置文本Text显示日期,设置文本颜色,添加箭头图片给row容器添加边距

使用swiper组件,将营养素统计NutrienrStats.ets与热量统计CaiorieStats.ets调用进行切换。

设置好swiper的宽和高,背景色

import { CommonConstants } from '../../common/constants/CommonConstants'
import DatePickDialog from './DatePickDialog'
import NutrientStats from './NutrientStats'
import CalorieStats from './CalorieStats'
import DateUtil from '../../common/utils/DateUtil'
@Component
@Preview
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)
      .indicatorStyle({selectedColor:$r('app.color.primary_color')})


    }
    .width(CommonConstants.THOUSANDTH_940)
    .backgroundColor($r('app.color.stats_title_bgc'))
    .borderRadius(CommonConstants.DEFAULT_18)
  }
}

四、热量统计卡片和营养素统计卡片设计:

按照实现思路:

在record文件夹下新建文件,用来定义热量

利用行式布局再在其中使用column布局,用text组件编辑文本,设置文本的字体的颜色与粗细。

按照上述步骤进行构建第二行与第三行,调整字体其颜色与粗细,通过.justfyContent调整布局为均匀分布,调整内边距上面留30,下面留25.

建立@Builder函数名为StatsBuilder,设置其变量,补充说明进行判断问号。

调用StatBuilder函数来构建,建立一个recommend函数来计算还可以吃的热量。

加上进度条,使用Stack()占用器设置Progress进度条,设置进度条的参数,如环的粗细,线的类型,颜色。

import { CommonConstants } from '../../common/constants/CommonConstants'
@Component
@Preview
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}){//间距为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('推荐1690')
          .fontSize(12)
          .fontColor($r('app.color.light_gray'))
      }
    }
  }
}

按照实现思路:

在record文件夹下新建NutrienrStats.ets文件,用来定义营养素

按照热量统计设计的步骤,添加碳水化合物,蛋白质,脂肪变量,设置好相对应传的参数

利用行式布局再在其中使用column布局,用text组件编辑文本,设置文本的字体的颜色与粗细。

按照上述步骤进行构建第二行与第三行,调整字体其颜色与粗细,通过.justfyContent调整布局为均匀分布,调整内边距上面留30,下面留25.

建立@Builder函数名为StatsBuilder,设置其变量,补充说明进行判断问号。

调用StatBuilder函数来构建,建立一个recommend函数来计算还可以吃的热量。

加上进度条,使用Stack()占用器设置Progress进度条,设置进度条的参数,如环的粗细,线的类型,颜色。

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}){//间距为6
      // 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: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.light_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'))

    }
  }
}

四、日期选择器设计:

按照实现思路:

在record文件夹下新建DatePickDialog.ets文件

设置弹窗controller,添加日期选择器,初始化selecteddate

设置日期开始日期和结束日期,设置取消与确定按钮,设置好各个按钮的大小与样式

为Column设置边距为12,设置按钮单击事件,保存日期到全局保存,在Appstorage.setorcreat中保存日期,设置关闭点击事件,在StatsCard.ets中做初始化并且导包,为DataPickDialog初始化,并传入日期date,通过@StrarageProp做单向传输做初始化,即为当前日期,DateUtill传入。最后添加点击事件。

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({
        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)
  }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值