一 项目目标
综合运用本学期所学内容及个人自学知识,使用HarmonyOS 4.0及以上版本开发一款具有实用性和创新
性的移动应用软件
二 项目介绍
黑马健康app是一款通过记录饮食,食物营养成分,以及提供运动可消耗热量的app,用户可以查看饮食记录帮助用户清晰的得知自己的个人身体热量与营养的摄入与消耗以及还可摄入多少热量
食物列表panel组件顶部日期
import { CommonConstants } from '../../common/constants/CommonConstants'
@Component
export default struct ItemPanelHeader {
build() {
Row(){
Text('2024年1月25日 早餐')
.fontSize(18).fontWeight(CommonConstants.FONT_WEIGHT_600)
Image($r('app.media.ic_public_spinner'))
.width(20)
.fillColor(Color.Black)
}
}
}
panel记录项卡片
import { CommonConstants } from '../../common/constants/CommonConstants'
import RecordItem from '../../viewmodel/RecordItem'
@Component
export default struct ItemCard {
@Prop amount: number
@Link item: RecordItem
build() {
Column({space: CommonConstants.SPACE_8}){
// 1.图片
Image(this.item.image).width(150)
// 2.名称
Row(){
Text(this.item.name).fontWeight(CommonConstants.FONT_WEIGHT_700)
}
.backgroundColor($r('app.color.lightest_primary_color'))
.padding({top: 5, bottom: 5, left: 12, right: 12})
Divider().width(CommonConstants.THOUSANDTH_940).opacity(0.6)
// 3.营养素
Row({space: CommonConstants.SPACE_8}){
this.NutrientInfo({label: '热量(千卡)', value: this.item.calorie})
if(this.item.id < 10000){
this.NutrientInfo({label: '碳水(千卡)', value: this.item.carbon})
this.NutrientInfo({label: '蛋白质(千卡)', value: this.item.protein})
this.NutrientInfo({label: '脂肪(千卡)', value: this.item.fat})
}
}
Divider().width(CommonConstants.THOUSANDTH_940).opacity(0.6)
// 4.数量
Row(){
Column({space: CommonConstants.SPACE_4}){
Text(this.amount.toFixed(1))
.fontSize(50).fontColor($r('app.color.primary_color'))
.fontWeight(CommonConstants.FONT_WEIGHT_600)
Divider().color($r('app.color.primary_color'))
}
.width(150)
Text(this.item.unit)
.fontColor($r('app.color.light_gray'))
.fontWeight(CommonConstants.FONT_WEIGHT_600)
}
}
}
@Builder NutrientInfo($$:{label: string, value: number}){
Column({space: CommonConstants.SPACE_8}){
Text($$.label).fontSize(14).fontColor($r('app.color.light_gray'))
Text(($$.value * this.amount).toFixed(1)).fontSize(18).fontWeight(CommonConstants.FONT_WEIGHT_700)
}
}
}
panel数字键盘
import { CommonConstants } from '../../common/constants/CommonConstants'
@Component
export default struct NumberKeyboard {
numbers: string[] = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '.']
@Link amount: number
@Link value: string
@Styles keyBoxStyle(){
.backgroundColor(Color.White)
.borderRadius(8)
.height(60)
}
build() {
Grid(){ //网格组件
ForEach(this.numbers, num => {
GridItem(){
Text(num).fontSize(20).fontWeight(CommonConstants.FONT_WEIGHT_900)
}
.keyBoxStyle()
.onClick(() => this.clickNumber(num))
})
GridItem(){
Text('删除').fontSize(20).fontWeight(CommonConstants.FONT_WEIGHT_900)
}
.keyBoxStyle()
.onClick(() => this.clickDelete())
}
.width('100%')
.height(280)
.backgroundColor($r('app.color.index_page_background'))
.columnsTemplate('1fr 1fr 1fr')
.columnsGap(8)
.rowsGap(8)
.padding(8)
.margin({top: 10})
}
clickNumber(num: string){
// 1.拼接用户输入的内容
let val = this.value + num
// 2.校验输入格式是否正确
let firstIndex = val.indexOf('.')
let lastIndex = val.lastIndexOf('.')
if(firstIndex !== lastIndex || (lastIndex != -1 && lastIndex < val.length - 2)){
// 非法输入
return
}
// 3.将字符串转为数值
let amount = this.parseFloat(val)
// 4.保存
if(amount >= 999.9){
this.amount = 999.0
this.value = '999'
}else{
this.amount = amount
this.value = val
}
}
clickDelete(){
if(this.value.length <= 0){
this.value = ''
this.amount = 0
return
}
this.value = this.value.substring(0, this.value.length - 1)
this.amount = this.parseFloat(this.value)
}
parseFloat(str: string){
if(!str){
return 0
}
if(str.endsWith('.')){
str = str.substring(0, str.length - 1)
}
return parseFloat(str)
}
}
总结:
1,导入了CommonConstants常量集,用于统一控制组件内部的样式,如字体加粗等。
组件定义,使用@Component装饰器定义了一个组件结构体,这是构建用户界面的一部分。
构建UI界面 (build方法):通过Row布局创建水平排列的内容,包含两部分:日期和时间段文本: 使用Text组件显示预设的日期(2024年1月25日)和时间段(早餐),设置字体大小为18,字体加粗。
动态加载图标: 通过Image组件展示一个旋转箭头图标(ic_public_spinner资源),宽度设置为20,并填充黑色,通常表示加载或刷新状态。
2,Prop amount通过属性接收用户选择的该记录项的数量Link item使用链接属性接收一个RecordItem实例,包含记录项的所有详细信息。使用Image组件展示记录项的图片,宽度固定为150。 通过Row布局展示记录项的名称,名称文本加粗,背景色轻微高亮,上下左右有内边距,下方跟随一条半透明的分割线。根据记录项类型,展示热量、碳水化合物、蛋白质和脂肪的详细信息。每个营养素信息由NutrientInfo构建器方法生成,显示营养素标签和基于数量计算的值。显示用户选择的数量,数值大且颜色突出,旁边标注单位,两者间有一条与数值颜色相同的分隔线。接收营养素的标签和原始值,计算出基于当前选择数量的实际摄入量,并以两行文本展示:上行为营养素标签(灰色小字体),下行为计算后的摄入量值(大字体加粗)。
3,使用Grid组件布局数字键盘,每行三个按钮,包括数字0-9和小数点。为每个数字按钮应用样式,并添加点击事件处理函数clickNumber。添加一个“删除”按钮,同样应用样式并关联点击事件处理函数clickDelete。设置整个键盘的宽高、背景色、网格列配置、间距等样式。