鸿蒙开发日志黑马健康(2)

一、项目目标

综合运用本学期所学内容及个人自学知识,使用HarmonyOS 4.0及以上版本开发一款具有实用性和创新  性的移动应用软件。

二、项目介绍

黑马健康是一款功能全面的健康管理应用,它通过提供个性化的饮食记录、健康评估等功能,帮助用户轻松管理健康,改善饮食和生活习惯。无论是需要减肥塑形,还是关注日常营养摄入,黑马健康都能为用户提供定制化的服务,让健康管理变得简单而有效。 

饮食部分UI设计

顶部导航栏设计

1.

2.

3.

4.第一部分搜索栏以及邮箱

5.

统计卡片

1.

2.

3.

4.

5.

6.CalorieStats组件

遇到的问题及解决方案

1.搜索栏及邮箱提示API方法的设置

Search({placeholder: '搜索饮食或运动信息'})

.textFont({size: 18})

.layoutWeight(1)

Badge({count: 1, position: BadgePosition.RightTop, style: {fontSize: 12}}){ Image($r('app.media.ic_public_email'))

.width(24)

search方法提供搜索栏,Badge提供角标

2.开发饮食记录UI界面时,实现顶部搜索栏使用日期滑动选择器

3.如何把日期选择器的日期保存到全局

// 1.保存日期到全局存储 AppStorage.SetOrCreate('selectedDate', this.selectedDate.getTime())

getTime()转成ms值去计算,selectedDate存到AppStorage

4.日期不一致

@StorageProp('selectedDate') selectedDate: number = DateUtil.beginTimeOfDay(new Date())

DateUtil.beginTimeOfDay(new Date()获取开始日期

把日期回显回去,在对话框补全,读取对话款的选中日期

builder: DatePickDialog({selectedDate: new Date(this.selectedDate)})

日期格式化展示时,使用selectedDate

Text(DateUtil.formatDate(this.selectedDate)) 把ms格式化成日期

5.如何让设置进度条

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}`}) }

使用Stack,为环绕关系

你最想分享的亮点

1.首页UI设计

Tabs组件可以实现页面内视图内容快速切换,包含TabBar和TabContent两个部分,

barPosition控制位置,.vertical控制水平还是竖直

Builder用来调整样式,可以改成文字加图片的样式,不使用自定义模板

代码

Index

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

WelcomePage

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

RecordIndex

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

SearchHeader

import { CommonConstants } from '../../common/constants/CommonConstants'
@Component
export default struct SearchHeader {
  build() {
    Row({space: CommonConstants.SPACE_6}){
      Search({placeholder: '搜索饮食或运动信息'})
        .textFont({size: 18})
        .layoutWeight(1)
      Badge({count: 1, position: BadgePosition.RightTop, style: {fontSize: 12}}){
        Image($r('app.media.ic_public_email'))
          .width(24)
      }
    }
    .width(CommonConstants.THOUSANDTH_940)
  }
}

StatsCard

import { CommonConstants } from '../../common/constants/CommonConstants'
import DateUtil from '../../common/utils/DateUtil'
import DatePickDialog from './DatePickDialog'

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

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

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

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

  • 27
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值