鸿蒙(HarmonyOS)应用开发——健康生活应用(5)

发布时间:2025-01-22 22:43

视力检查应在5岁后开始,定期监测防止近视发生。 #生活常识# #育儿常识# #儿童健康检查#

健康生活应用参考了黑马程序员实战案例45.实战案例-数据模型-记录项_哔哩哔哩_bilibili

鸿蒙应用开发:打造智能饮食统计与个性化推荐系统

一、引言

在健康管理应用中,智能统计与个性化推荐是提升用户体验的两大核心功能。本文将详细介绍如何在鸿蒙应用中实现这些功能,特别是统计信息的展示设计和日期选择器的用户交互设计。

二、饮食统计功能设计

1、设计理念

饮食统计功能的设计旨在为用户提供直观的饮食摄入和消耗数据,并通过与推荐摄入量的对比,帮助用户更好地管理自己的饮食习惯。

2、关键组件设计 StatsCard:作为饮食统计的核心容器,展示每日的热量摄入、消耗和营养素摄入。CalorieStats:展示热量摄入、消耗和剩余可摄入量,通过环形进度条形象化展示。NutrientStats:展示碳水化合物、蛋白质和脂肪的摄入量,并与推荐摄入量进行对比。 3、统计信息展示设计

使用Swiper组件实现信息的左右滑动切换,用户可以方便地查看不同类型的统计信息。

三、日期选择器设计

1、设计理念

日期选择器允许用户选择特定的日期,以便查看或对比不同日期的饮食统计数据。

2、关键组件设计 DatePickDialog:自定义弹窗组件,集成了DatePicker日期选择器,提供日期选择和确认操作。 3、用户交互设计 用户点击日期信息区域,触发DatePickDialog弹窗的显示。用户在弹窗中选择日期后,可以选择“取消”或“确定”。点击“确定”后,所选日期将保存并关闭弹窗。

四、代码实现

1、StatsCard 组件实现

import BreakpointType from '../../common/bean/BreanpointType'

import BreakpointConstants from '../../common/constants/BreakpointConstants'

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

import DateUtil from '../../common/utils/DateUtil'

import RecordService from '../../service/RecordService'

import RecordVO from '../../viewmodel/RecordVO'

import StatsInfo from '../../viewmodel/StatsInfo'

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

@StorageProp('currentBreakpoint') currentBreakpoint: string = BreakpointConstants.BREAKPOINT_SM

@Consume @Watch('handleRecordsChange') records: RecordVO[]

@State info: StatsInfo = new StatsInfo();//渲染,当监控到record变化的时候

//计算

handleRecordsChange(){

this.info = RecordService.calculateStatsInfo(this.records)

}

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({intake: this.info.intake, expend: this.info.expend})

// 2.2.营养素统计

NutrientStats({carbon: this.info.carbon, protein: this.info.protein, fat: this.info.fat})

}

.width('100%')

.backgroundColor(Color.White)

.borderRadius(CommonConstants.DEFAULT_18)

.indicatorStyle({selectedColor: $r('app.color.primary_color')})

.displayCount(new BreakpointType({

sm: 1,

md: 1,

lg: 2

}).getValue(this.currentBreakpoint))

}

.width(CommonConstants.THOUSANDTH_940)

.backgroundColor($r('app.color.stats_title_bgc'))

.borderRadius(CommonConstants.DEFAULT_18)

}

}

2、DatePickDialog 自定义弹窗实现

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)

}

}

3、CalorieStats 和 NutrientStats 组件实现

这两个组件的实现逻辑与StatsCard类似,主要区别在于它们展示的具体统计数据不同。CalorieStats关注热量摄入和消耗,而NutrientStats关注营养素的摄入。

CalorieStats:

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

@Component

export default struct CalorieStats {

@Prop intake: number

@Prop expend: number

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:

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

@Component

export default struct NutrientStats {

@Prop carbon: number

@Prop protein: number

@Prop fat: number

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'))

}

}

}

五、结论

本文介绍了鸿蒙应用中饮食统计和个性化推荐功能的实现方法,特别是统计信息的展示设计和日期选择器的用户交互设计。

网址:鸿蒙(HarmonyOS)应用开发——健康生活应用(5) https://www.yuejiaxmz.com/news/view/736353

相关内容

鸿蒙HarmonyOS应用开发
鸿蒙(HarmonyOS)应用开发——健康生活应用(4)
鸿蒙应用
鸿蒙应用开发教程第02期:完整开发流程,速戳!
鸿蒙原生版建设银行上架原生鸿蒙应用市场,全方位守护用户隐私安全
纯血鸿蒙含“金”量飙升!超 400 款金融理财应用已上架鸿蒙原生版
纯血鸿蒙含“金”量飙升!超400款金融理财应用已上架鸿蒙原生版
用 HarmonyOS ArkUI 来开发一个健康饮食应用
便捷生活场景再扩张!叮咚买菜启动鸿蒙原生应用开发
便捷生活场景再扩张!叮咚买菜启动鸿蒙原生应用开发

随便看看