鸿蒙实战案例-食物列表-底部Panel及数字键盘


前言

随着健康意识的提升,许多人开始关注自己的饮食健康,记录每天的饮食情况成为了日常的一部分。今天,我们将继续来构建一个简单的食品记录应用,帮助用户更好地管理他们的饮食。


一、UI设计分析

二、应用结构

我们的应用将分为四个主要部分:顶部日期、记录项卡片、数字键盘和按钮。每个部分负责不同的功能和显示不同的信息。

整体效果图:

1.引导页面

代码如下:

   底部面板
      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})

2.顶部日期ItemPanelHeader

由于后期还会进行补充·,目前我们先把日期写死,感兴趣的也可以参考一下鸿蒙实战案例-饮食记录-统计卡片-CSDN博客

代码如下:

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)

    }
  }
}

效果图:

3.记录项卡片ItemCard

ItemCard组件主要用于展示食品项目的详细信息,使用Image组件展示食品的图片,宽度设置为150px。使用Row和Text组件展示食品的名称,字体加粗以突出显示。同时,为名称添加背景色,并设置内边距。使用Divider组件添加分割线,用于分隔不同的信息区域,提高可读性。使用Row和NutrientInfo方法展示食品的营养素信息,包括热量、碳水、蛋白质和脂肪等。每种营养素占据一行,展示其标签和对应的数值。在营养素信息下方再次添加分割线,用于分隔数量信息。使用Row和Column组件展示食品的数量,包括数字和单位(片)。数字部分使用较大的字体和主题颜色突出显示,单位部分使用较小的字体和浅灰色显示。此外,组件还定义了一个名为NutrientInfo的方法,用于根据传入的标签和数值生成一个包含营养素信息的Column组件。这个方法接收两个参数:label(标签)和value(数值),然后创建一个Column组件,其中包含两个Text组件,分别展示标签和数值。

代码如下:

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*this.amount).toFixed(1)).fontSize(18).fontWeight(CommonConstants.FONT_WEIGHT_700)

    }
  }
}

效果图:

4.数字键盘NumberKeyboard

NumberKeyboard组件的主要功能是生成一个数字键盘界面。使用Grid和GridItem组件生成一个3x4的数字键盘布局,每个数字或删除键都由一个GridItem组件表示。当用户点击数字键时,会触发clickNumber方法,该方法将用户输入的内容拼接起来,并校验输入格式是否正确。如果输入合法,则将字符串转为数值,并将结果保存到amount属性中。如果输入不合法,则不做任何操作。当用户点击删除键时,会触发clickDelete方法,该方法会删除value属性中的最后一个字符,并将结果保存到amount属性中。在clickNumber方法中,使用parseFloat方法对输入内容进行格式化处理,去除末尾的"."符号,并将其转换为浮点数类型。

代码如下:

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)
    .height(60)
    .borderRadius(8)
  }
  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.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.0
      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)
  }
}

效果图:


总结

这篇文章主要介绍了一个食品记录应用程序的底部面板,包括顶部日期、记录项卡片和数字键盘等组件。其中,顶部日期显示了当前的日期和时间;记录项卡片展示了每餐所摄入的食品信息,包括图片、名称、营养素信息和数量;数字键盘则用于输入食品的数量。通过这个应用程序,用户可以方便地记录每天所摄入的食品和营养素信息,更好地管理自己的饮食健康。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值