前言
本文将介绍如何使用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来展示用户摄入的碳水化合物、蛋白质和脂肪的统计数据。