鸿蒙作业HealthApp第六期

食物列表



前言

本期主要讲解食物列表的创建,主要分为底部Panel的创建和数字键盘的创建。


一、 底部面板的结构分析

如图所示:
在这里插入图片描述

二、 食物列表-底部Panel

2.1顶部日期

如图所示:
在这里插入图片描述
代码如下:

import { CommonConstants } from '../../common/constants/CommonConstants'
@Component
export default struct ItemPanelHeader {
  build() {
    Row(){
      Text('2024年1月25号 早餐')
        .fontSize(18)
        .fontWeight(CommonConstants.FONT_WEIGHT_600)
      Image($r('app.media.ic_public_spinner'))
        .width(20)
        .fillColor(Color.Black)

    }
  }
}

2.2记录项卡片

如图所示:
在这里插入图片描述
代码如下:

import { CommonConstants } from '../../common/constants/CommonConstants'
import RecordItem from '../../viewmodel/RecordItem'
@Component
export default struct ItemCard {
  @Prop amount: number//状态变量 Prop不能初始化
  @Link item:RecordItem

  build() {
    Column({space:CommonConstants.SPACE_8}){
      //1.图片
      Image(this.item.image).width(150)
      //2.名称
      Row(){
        Text(this.item.name) .fontWeight(CommonConstants.FONT_WEIGHT_700)//为了添加颜色 将其放入Row容器中
      }
      .backgroundColor($r('app.color.lightest_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({label:'热量(千卡)',value:this.item.calorie})
        if(this.item.id< 10000) {
          this.NutrientInfo({label:'碳水(克)', value:this.item.carbon})
          this.NutrientInfo({label:'蛋白质(克)', value:this.item.protein})
          this.NutrientInfo({label:'脂肪(克)',value: this.item.fat})
        }

      }
      Divider()//下划线
        .width(CommonConstants.THOUSANDTH_940)
        .opacity(0.6)//透明度
      //4.数量
      Row(){
        Column({space:CommonConstants.SPACE_4}){
          Text(this.amount.toFixed(1))//1位小数
            .fontSize(50).fontColor($r('app.color.primary_color'))
            .fontWeight(CommonConstants.FONT_WEIGHT_600)
          Divider().color($r('app.color.primary_color'))
        }
        .width(150)
        Text(this.item.unit)
          .fontColor($r('app.color.primary_color'))
          .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+this.amount).toFixed(1))//一位小数
        .fontSize(18).fontWeight(CommonConstants.FONT_WEIGHT_700)
    }
  }
}

三、食物列表-数字键盘

如图所示:
在这里插入图片描述
代码如下:

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

  numbers: string[]=['1','2','3','4','5','6','7','8','9','0','.']//why?
  @Link amount:number//Link双向绑定
  @Link value:string

@Styles keyBoxStyle(){
  .backgroundColor(Color.White)
  .borderRadius(8)//圆角
  .height(60)
}


  build() {
    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.clickDelect())

    }
    .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('.')//记录val里面的小数点 从前往后
    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.0
      this.value='999'
    }else{
      this.amount=amount
      this.value=val
    }
  }
  clickDelect(){
    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)
  }
  //3.(1) 转换
  parseFloat(str:string){
    if(!str){
      return 0;
    }
    if(str.endsWith('.')){//是否以'.'结尾
      str=str.substring(0,str.length-1)//去除最后一位 从0开始去除 一直到长度减一
    }
    return parseFloat(str)
  }
}

总结

  • clickNumber方法处理用户点击数字或小数点的逻辑: 拼接用户输入的内容到value。
  • 校验输入格式,确保只有一个小数点且小数点后不超过两位。
  • 将字符串转换为数值,并保存到amount中。
  • 如果输入超过999.9,则限制为999.0。
  • clickDelect方法处理用户点击“删除”按钮的逻辑:
  • 如果value为空,则重置value和amount为0。 否则,删除value的最后一个字符,并更新amount。
  • 8
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值