黑马健康期末项目3

黑马健康期末项目3



前言

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


一、项目名称:黑马健康

黑马健康是一款面向健康管理机构及用户的软件,它提供了丰富的健康管理功能,旨在提高健康管理师的工作效率,加强与患者间的互动,并增强管理者对健康管理机构运营情况的了解。

二、运行过程

1.食物列表页

思维导图:

在这里插入图片描述

运行截图:

在这里插入图片描述

代码如下(部分):

import { CommonConstants } from '../../common/constants/CommonConstants'
@Component
export default struct ItemList {
  build() {
    Tabs(){
      TabContent(){
        this.TabContentBuilder()
      }
      .tabBar('全部')

      TabContent(){
        this.TabContentBuilder()
      }
      .tabBar('主食')

      TabContent(){
        this.TabContentBuilder()
      }
      .tabBar('肉蛋奶')
    }
    .width(CommonConstants.THOUSANDTH_940)//宽度
    .height('100%')
  }

  @Builder TabContentBuilder(){
    List({space:CommonConstants.SPACE_10}){
      ForEach([1,2,3,4,5,6],(item)=>{
        ListItem(){
          Row({space:CommonConstants.SPACE_6}){//行内元素之间的间距
            Image($r('app.media.toast')).width(50)
            Column({space:CommonConstants.SPACE_4}){
              Text('全麦吐司').fontWeight(CommonConstants.FONT_WEIGHT_500)//字体加粗
              Text('91千卡/片').fontSize(14).fontColor($r('app.color.light_gray'))
            }
            Blank()
            Image($r('app.media.ic_public_add_norm_filled'))
              .width(18)
              .fillColor($r('app.color.primary_color'))//填充颜色
          }
          .width('100%')
          .padding(CommonConstants.SPACE_6)
        }
      })
    }
    .width('100%')
    .height('100%')
  }
}

2.食物列表——底部Panel

思维导图:

在这里插入图片描述

运行截图:

在这里插入图片描述

代码如下(部分):

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

  @Prop amount:number
  build() {
    Column({space:CommonConstants.SPACE_8}){
      //1.图片
      Image($r('app.media.toast')).width(150)
      //2.名称
      Row(){
        Text('全麦吐司').fontWeight(CommonConstants.FONT_WEIGHT_700)
      }
      .backgroundColor($r('app.color.light_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('热量(千卡)',91.0)
        this.NutrientInfo('碳水(克)',15.5)
        this.NutrientInfo('蛋白质(克)',4.4)
        this.NutrientInfo('脂肪(克)',1.3)
      }
      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('片')
         .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.toFixed(1)).fontSize(18).fontWeight(CommonConstants.FONT_WEIGHT_700)
    }
  }
}

3.食物列表——数字键盘

思维导图:

在这里插入图片描述

运行截图

在这里插入图片描述

代码如下(部分):

//NumberKeyboard.ets
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:网格容器,由行和列分割的单元格组成,通过指定项目所在的单元格做出各种各样的布局
    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.9
      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)
  }
}

//ItemIndex.ets
import router from '@ohos.router'
import { CommonConstants } from '../common/constants/CommonConstants'
import ItemCard from '../view/item/ItemCard'
import ItemList from '../view/item/ItemList'
import ItemPanelHeader from '../view/item/ItemPanelHeader'
import NumberKeyboard from '../view/item/NumberKeyboard'
@Entry
@Component
struct ItemIndex {
  @State amount:number=1
  @State value:string=''
  @State showPanel:boolean=false

  onPageShow(){
    this.amount=1
    this.value=''
    this.showPanel=true
  }

  build() {
    Column() {
      //1.头部导航
      this.Header()
      //2.列表
      ItemList({showPanel:this.onPageShow.bind(this)})
      .layoutWeight(1)
      //3.底部面板
      Panel(this.showPanel){
        //3.1.顶部日期
        ItemPanelHeader()
        //3.2.记录项卡片
        ItemCard({amount:this.amount})
        //3.3.数字键盘
        NumberKeyboard({amount:$amount,value:$value})
        //3.4.按钮
        Row({space:CommonConstants.SPACE_6}){
          Button('取消')
            .width(120)
            .backgroundColor($r('app.color.light_gray'))
            .type(ButtonType.Normal)
            .borderRadius(6)
            .onClick(()=>this.showPanel=false)
          Button('提交')
            .width(120)
            .backgroundColor($r('app.color.primary_color'))
            .type(ButtonType.Normal)
            .borderRadius(6)
            .onClick(()=>this.showPanel=false)
        }
        .margin({top:10})

      }
      .mode(PanelMode.Full)
      .dragBar(false)
      .backgroundMask($r('app.color.light_gray'))
      .backgroundColor(Color.White)
    }
    .width('100%')
    .height('100%')
  }


  @Builder Header(){
    Row(){
       Image($r('app.media.ic_public_back'))
         .width(24)
         .onClick(()=>router.back())
      Blank()
      Text('早餐').fontSize(18).fontWeight(CommonConstants.FONT_WEIGHT_600)
    }
    .width(CommonConstants.THOUSANDTH_940)
    .height(32)
  }
}

总结

1.食物列表页

当用户点击食物信息时,会弹出一个面板。面板上有食物的详细信息,包括热量和营养素等等。然后用户还可以去选择想要添加的食物的数量点击提交,就会完成一项饮食记录的添加。
整个页面呈现一个从上到下的格局,我们可以使用Column()容器。同样,整个容器会占满整个页面,所以宽度和高度都为100%。width(‘100%’)以及height(‘100%’)

2.食物列表——底部Panel

整个样式是一个从上到下的列式布局,所以还是用一个Column().width(‘100%’).height(‘100%’),宽和高都为100%。从上到下是是简单的行式布局。
首先第一行展示的是一个文本和一个小图标,表示日期和早餐。
第二行是一个居中显示的图片。
第三行是显示食物的名称,外加一个背景色。
第四行是食物的详细信息,为上下布局。上方是热量(单位),下方是具体值。
第五行是食物的数量,分为两部分,左边为数量,右边为单位。

3.食物列表——数字键盘

数字键盘所用到的组件时我们之前从来没有用到过的,是一个名为Grid的组件。
Grid为网格容器,由“行”和“列”分割的单元格所组成,通过指定“项目”所在的单元格做出各种各样的布局。
子组件:包含GridItem子组件。
Grid子组件的索引值计算规则:
1.按子组件的顺序依次递增。
2.if/else语句中,只有条件成立分支内的子组件会参与索引值计算,条件不成立分支内的子组件不计算索引值。
3.ForEach/LazyForEach语句中,会计算展开所有子节点索引值。
4.if/else/ForEach/LazyForEach发生变化以后,会更新子节点索引值。
5.Grid子组件的visibility属性设置为Hidden或None时依然会计算索引值。
6.Grid子组件的visibility属性设置为None时不显示,但依然会占用子组件对应的网格。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值