首頁 資訊 HarmonyOS5 運(yùn)動(dòng)健康app(一):健康飲食(附代碼)

HarmonyOS5 運(yùn)動(dòng)健康app(一):健康飲食(附代碼)

來源:泰然健康網(wǎng) 時(shí)間:2025年07月03日 21:21

image.png

飲食管理應(yīng)用架構(gòu)設(shè)計(jì)文檔

一、核心數(shù)據(jù)模型設(shè)計(jì)

1. 營養(yǎng)元素模型 (footItem)

interface footItem { name: string; // 營養(yǎng)名稱(蛋白質(zhì)/碳水/脂肪) weight: number; // 重量(克) }2. 食物模型 (DietItem)

interface DietItem { name: string; // 食物名稱 image: string; // 圖片路徑(如app.media.mantou) weight: number; // 單份重量(克) calorie: number; // 單份卡路里 count: number; // 食用數(shù)量 nengliang: string; // 主要營養(yǎng)素類型 }

設(shè)計(jì)說明

footItem 將蛋白質(zhì)、碳水、脂肪抽象為基礎(chǔ)單元DietItem 包含物理屬性+營養(yǎng)屬性,nengliang字段建立食物與營養(yǎng)素的映射關(guān)系

二、主組件架構(gòu):Index組件

狀態(tài)管理

@State progressIndex: number = 0 // 總卡路里 @State dbzIndex: number = 0 // 總蛋白質(zhì) @State tsIndex: number = 0 // 總碳水 @State zfIndex: number = 0 // 總脂肪頭部統(tǒng)計(jì)組件 (toubu)

@Builder toubu() { Column({ space: 15 }) { // 環(huán)形卡路里進(jìn)度條 Stack() { Progress({ value: this.progressIndex, total: 20000, type: ProgressType.Ring }) .width(90).height(90).style({ strokeWidth: 10 }) Text(`${this.progressIndex} kcal`).fontSize(14).fontWeight(FontWeight.Bold) } // 營養(yǎng)素統(tǒng)計(jì)行 Row() { ForEach(footData, (item) => { Column() { Text(this.getItemWeight(item).toString()).fontSize(18) Text(item.name).fontSize(14) }.width('30%') }) } } }

功能特點(diǎn)

環(huán)形進(jìn)度條目標(biāo)值20000kcal營養(yǎng)素統(tǒng)計(jì)行實(shí)時(shí)顯示三類營養(yǎng)素?cái)z入量

三、可復(fù)用組件:foods組件

核心屬性

@State ifjiajian: boolean = false // 操作類型(增減) @Prop item: DietItem // 食物對(duì)象(只讀) @Link progressIndex: number // 雙向綁定總卡路里 @Link dbzIndex: number // 雙向綁定蛋白質(zhì)關(guān)鍵方法

// 卡路里計(jì)算 calorieNUm() { const num = this.ifjiajian ? this.item.calorie * this.item.count : -this.item.calorie * (this.item.count + 1) this.progressIndex += num } // 營養(yǎng)素計(jì)算 weightNUm() { const amount = this.ifjiajian ? this.item.count : -(this.item.count + 1) const weightChange = 13 * amount switch(this.item.nengliang) { case '蛋白質(zhì)': this.dbzIndex += weightChange case '碳水': this.tsIndex += weightChange case '脂肪': this.zfIndex += weightChange } }

四、數(shù)據(jù)流轉(zhuǎn)閉環(huán)

用戶操作 → 點(diǎn)擊"+"按鈕

item.count++ifjiajian = true

數(shù)據(jù)計(jì)算

calorieNUm()計(jì)算新增卡路里weightNUm()更新對(duì)應(yīng)營養(yǎng)素

界面更新

環(huán)形進(jìn)度條自動(dòng)刷新營養(yǎng)素?cái)?shù)值實(shí)時(shí)更新

五、完整代碼

<details>
<summary>點(diǎn)擊查看完整實(shí)現(xiàn)</summary>

interface footItem { name: string; // 營養(yǎng)名稱 weight: number; // 重量 } interface DietItem { name: string; // 食物名稱 image: string; // 食物圖片路徑(本地或網(wǎng)絡(luò),這里用占位示意) weight: number; // 重量 calorie: number; // 卡路里 count: number; // 食用數(shù)量 nengliang: string; // 營養(yǎng)名稱(蛋白質(zhì)、脂肪、碳水) } const footData: footItem[] = [ { name: '蛋白質(zhì)', weight: 0 }, { name: '碳水', weight: 0 }, { name: '脂肪', weight: 0 }, ]; const dietData: DietItem[] = [ { name: '饅頭', image: 'app.media.mantou', weight: 13, calorie: 100, count: 0, nengliang: '蛋白質(zhì)' }, { name: '油條', image: 'app.media.youtiao', weight: 13, calorie: 200, count: 0, nengliang: '脂肪' }, { name: '豆?jié){', image: 'app.media.doujiang', weight: 13, calorie: 300, count: 0, nengliang: '碳水' }, { name: '稀飯', image: 'app.media.xifan', weight: 13, calorie: 300, count: 0, nengliang: '碳水' }, { name: '雞蛋', image: 'app.media.egg', weight: 13, calorie: 200, count: 0, nengliang: '蛋白質(zhì)' }, ]; @Entry @Component export struct Index { @State progressIndex: number = 0 // 進(jìn)度條進(jìn)度(總大卡數(shù)) @State dbzIndex: number = 0 // 總蛋白質(zhì) @State tsIndex: number = 0 // 總碳水 @State zfIndex: number = 0 // 總脂肪 // 頭部組件 @Builder toubu() { Column({ space: 15 }) { Stack() { Progress({ value: this.progressIndex, total: 20000, type: ProgressType.Ring }) .width(90) .height(90) .style({ strokeWidth: 10 }) .color('#4CD964') .backgroundColor('#e0e0e0'); Text(`${this.progressIndex} kcal`) .fontSize(14) .fontWeight(FontWeight.Bold) .margin({ top: 5 }) } Row() { ForEach(footData, (item: footItem) => { Column() { Text(this.getItemWeight(item).toString()) .fontSize(18) .fontWeight(FontWeight.Bold) .fontColor('#333') Text(item.name) .fontSize(14) .fontColor('#666') } .width('30%') }, (item: footItem) => JSON.stringify(item)) } } .padding({ top: 20, bottom: 15 }) .width('100%') .alignItems(HorizontalAlign.Center) } // 獲取對(duì)應(yīng)的營養(yǎng)值 private getItemWeight(item: footItem): number { switch (item.name) { case '蛋白質(zhì)': return this.dbzIndex; case '碳水': return this.tsIndex; case '脂肪': return this.zfIndex; default: return 0; } } build() { Column({ space: 15 }) { this.toubu() Text('飲食內(nèi)容') .fontSize(20) .fontColor('#555') .width('100%') .margin({ left: 20 }) List({ space: 10 }) { ForEach(dietData, (item: DietItem) => { ListItem() { foods({ item: item, progressIndex: this.progressIndex, dbzIndex: this.dbzIndex, tsIndex: this.tsIndex, zfIndex: this.zfIndex }) } }, (item: DietItem) => JSON.stringify(item)) } } .width('100%') .padding({ left: 10,right: 10 }) } } // 飲食內(nèi)容組件 @Reusable @Component export struct foods { @State ifjiajian: boolean = false @Prop item: DietItem @Link progressIndex: number @Link dbzIndex: number @Link tsIndex: number @Link zfIndex: number // 統(tǒng)計(jì)大卡數(shù) calorieNUm() { let num = this.ifjiajian ? this.item.calorie * this.item.count : -this.item.calorie * (this.item.count + 1); this.progressIndex += num; } // 統(tǒng)計(jì)能量 weightNUm() { const amount = this.ifjiajian ? this.item.count : -(this.item.count + 1); const weightChange = 13 * amount; switch (this.item.nengliang) { case '蛋白質(zhì)': this.dbzIndex += weightChange; break; case '碳水': this.tsIndex += weightChange; break; case '脂肪': this.zfIndex += weightChange; break; } } build() { Row() { Image($r(this.item.image)) .width(60) .height(60) .borderRadius(8) Column({ space: 6 }) { Text(this.item.name) .fontSize(16) .fontWeight(FontWeight.Bold) Text(`${this.item.weight} 克`) .fontSize(14) .fontColor('#777') } .width('40%') .alignItems(HorizontalAlign.Start) Column({ space: 6 }) { Text(`${this.item.calorie * this.item.count} 卡`) .fontSize(16) .fontColor('#555') Row() { Text('-') .fontSize(20) .width(25) .height(25) .textAlign(TextAlign.Center) .borderRadius(4) .border({ width: 1, color: '#ccc' }) .onClick(() => { if (this.item.count > 0) { this.item.count--; this.ifjiajian = false; this.calorieNUm(); this.weightNUm(); } }) Text(`${this.item.count}`) .fontSize(16) .width(30) .textAlign(TextAlign.Center) Text('+') .fontSize(20) .width(25) .height(25) .textAlign(TextAlign.Center) .borderRadius(4) .border({ width: 1, color: '#ccc' }) .onClick(() => { this.item.count++; this.ifjiajian = true; this.calorieNUm(); this.weightNUm(); }) } .justifyContent(FlexAlign.SpaceAround) .width(90) } .width('40%') .alignItems(HorizontalAlign.Center) } .width('100%') .padding({ left: 10, right: 10 }) .justifyContent(FlexAlign.SpaceBetween) } }

</details>

相關(guān)知識(shí)

飲食熱量app開發(fā)源碼 健康飲食運(yùn)動(dòng)減脂app小程序設(shè)計(jì)制作開發(fā)源碼出售
春運(yùn)全國健康碼百度APP怎么申領(lǐng)?附流程圖解
健康運(yùn)動(dòng)健身系統(tǒng)app開發(fā)
小米運(yùn)動(dòng)健康app怎么記錄飲食
華為運(yùn)動(dòng)健康app如何升級(jí) 華為運(yùn)動(dòng)健康app?
湖北健康碼app
支付寶APP健康碼全國一碼通行怎么弄?附申請(qǐng)流程
河南健康碼app
下載安裝華為運(yùn)動(dòng)健康A(chǔ)pp
健康飲食APP開發(fā)健康食譜APP源碼定制APP開發(fā)方案

網(wǎng)址: HarmonyOS5 運(yùn)動(dòng)健康app(一):健康飲食(附代碼) http://m.u1s5d6.cn/newsview1501083.html

推薦資訊