鸿蒙实战项目-黑马健康应用开发日志二

目录

前言

一、项目目标

二、项目介绍

三、具体页面实现

1.首页Tabs

(1)页面分析:

(2)页面实现代码:

(3)运行效果:

2.饮食部分UI设计-顶部导航栏

(1)页面分析:

(2)页面实现代码:

(3)运行效果:

3.统计卡片设计

(1)页面分析:

(2)页面实现代码:

(3)运行效果:

总结



前言

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

一、项目目标

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

二、项目介绍

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

三、具体页面实现

1.首页Tabs

(1)页面分析:

整个首页是使用一个Tabs组件进行构建,Tabs组件可以实现页面内试图内容快速切换,包含TabBar和Tabcontent两个部分。

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

该app共有三个页面,分别为饮食记录页面,发现页面和我的页面,所以需要在Tabs组件中设置三个Tabcontent与TabBar(主要介绍饮食记录页面)

(2)页面实现代码:
import BreakpointType from '../common/bean/BreanpointType'
import { CommonConstants } from '../common/constants/CommonConstants'
import BreakpointSystem from '../common/utils/BreakpointSystem'
import RecordIndex from '../view/record/RecordIndex'
@Entry
@Component
struct Index {
  @State currentIndex:number = 0
  private breakpointSystem:BreakpointSystem = new BreakpointSystem()
  @StorageProp('currentBreakpoint') currentBreakpoint:string= 'sm'

  @Builder TabBarBuilder(title:ResourceStr, image:ResourceStr,index:number){
    Column({space:CommonConstants.SPACE_8}){
      Image(image)
        .width(22)
        .fillColor(this.selectColor(index))
      Text(title)
        .fontSize(14)
        .fontColor(this.selectColor(index))
    }
  }

  aboutToAppear(){
    this.breakpointSystem.register()
  }

  aboutToDisappear(){
    this.breakpointSystem.unregister()
  }

  selectColor(index:number){
    return this.currentIndex === index ? $r('app.color.primary_color') : $r('app.color.gray')
  }

  chooseBarPosition(){
    let p = {
      sm:BarPosition.End,
      md:BarPosition.Start,
      lg:BarPosition.Start
    }
    return p[this.currentBreakpoint]
  }

  build() {
    Tabs({barPosition:this.chooseBarPosition()}) {
      TabContent(){
        RecordIndex()
      }
      .tabBar(this.TabBarBuilder($r('app.string.tab_record'),$r('app.media.ic_calendar'),0))

      TabContent(){
        Text('发现页面')
      }
      .tabBar(this.TabBarBuilder($r('app.string.tab_discover'),$r('app.media.discover'),1))

      TabContent(){
        Text('我的页面')
      }
      .tabBar(this.TabBarBuilder($r('app.string.tab_user'),$r('app.media.ic_user_portrait'),2))
    }
    .width('100%')
    .height('100%')
    .onChange(index => this.currentIndex = index)
    .vertical(new BreakpointType({
      sm:false,
      md:true,
      lg:true
    }).getValue(this.currentBreakpoint))
  }
}
(3)运行效果:

2.饮食部分UI设计-顶部导航栏

(1)页面分析:

该页面顶部是一个搜索栏,创建单独组件SearchHeader,表示头部搜索栏。

(2)页面实现代码:
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)
  }
}
(3)运行效果:

3.统计卡片设计

(1)页面分析:

统计卡片分为两部分,包括日期、统计卡路里卡片,用row容器存储

卡片使用DatePicker日期选择组件,用于根据指定日期范围创建日期滑动选择器;使用Swiper滑块视图容器,提供子组件滑动轮播显示的能力。

(2)页面实现代码:

NutrientStats.ets

import { CommonConstants } from '../../common/constants/CommonConstants'
@Component
export default struct NutrientStats {

  carbon:number= 20
  protein:number= 30
  fat:number = 40

  recommendCarbon:number = CommonConstants.RECOMMEND_CARBON
  recommendProtein:number = CommonConstants.RECOMMEND_PROTEIN
  recommendFat:number = CommonConstants.RECOMMEND_FAT

  build() {
    Row({space:CommonConstants.SPACE_6}){
      this.statsBuilder(
        '碳水化合物',
        this.carbon,
        this.recommendCarbon,
        $r('app.color.carbon_color')
      )
      this.statsBuilder(
        '蛋白质',
        this.protein,
        this.recommendProtein,
        $r('app.color.protein_color')
      )
      this.statsBuilder(
        '脂肪',
        this.fat,
        this.recommendFat,
        $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(90)
          .style({strokeWidth:CommonConstants.DEFAULT_6})
          .color(color)
        Column({space:CommonConstants.SPACE_4}){
          Text('摄入推荐')
            .fontSize(14)
            .fontColor($r('app.color.gray'))
          Text(`${value.toFixed(0)}/${recommend.toFixed(0)}`)
            .fontSize(18)
            .fontWeight(CommonConstants.FONT_WEIGHT_700)
        }
      }
      Text(`${label} (克) `)
        .fontSize(12)
        .fontColor($r('app.color.light_gray'))
    }
  }
}

DatePickDialog.ets

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.ets

import { CommonConstants } from '../../common/constants/CommonConstants'
@Component
export default struct CalorieStats {
  intake:number = 192
  expend:number = 120
  recommend:number = CommonConstants.RECOMMEND_CALORIE
  remainCalorie(){
    return this.recommend-this.intake+this.expend
  }
  build() {
    Row({space:CommonConstants.SPACE_6}){
      //饮食摄入
      this.statsBuilder('饮食摄入',this.intake)
      //还能吃
      Stack(){
        //进度条
        Progress({
          value:this.recommend-this.remainCalorie(),
          total:this.recommend,
          type:ProgressType.Ring
        })
          .width(120)
          .style({strokeWidth:CommonConstants.DEFAULT_10})
          .color($r('app.color.primary_color'))
        //数据
        this.statsBuilder('还能吃',this.remainCalorie(),`推荐${this.recommend}`)
      }
      //运动消耗
      this.statsBuilder('运动消耗',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'))
      }

    }
  }
}
(3)运行效果:


总结

学会使用DatePicker和Swiper两个新的组件进行信息展示

  • 5
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值