【黑马健康APP--食物列表底部面版实现】

  本章需要食物列表页的底部面板部分,实现点击食物弹出底部面板的界面,包括顶部日期记录项、卡片数字键盘和按钮,实现动态底部面板。

一.运行效果

二.知识储备

    (一)Divider:提供分隔器组件,分隔不同内容块/内容元素。

          目标:实现显示营养素统计分割布局,层次分明底部面板。

    (二)Panel容器:可滑动面板,提供一种轻量的内容展示窗口,方便在不同尺寸中切换。

          目标:掌握利用Panel容器构成记录项卡片的滑动面板。

    (三)Grid组件:网格容器,由“行”和“列”分割的单元格所组成,通过指定“项目”所在的单元格做出各种各样的布局。

          目标:利用子组件GridItem子组件生成键盘,掌握Grid子组件的索引值计算规则,保证键盘输入信息的正确性。

三.实现步骤

(一)分析列表页面结构:

(二)底部面板用Panel容器完成,里嵌套日期记录项、卡片数字键盘和按钮的项。Item目录下新建ItemPanelHeader、ItemCard、NumberKeyboard分别用来展示顶部日期、完成食物营养素统计信息和数字键盘。最后在Panel容器最后一份设置代码,实现该底部面板的开发。

  • 底部面板用Panel容器大体框架
 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})
        }
  • 顶部日期显示区域代码实现

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

  }
}
  • 记录卡信息统计区域代码实现

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.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)
    }
  }
}
  • 记录卡信息统计区域代码实现

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(){
      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.parFloat(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.parFloat(this.value)
  }
  parFloat(str:string){
    if(!str){
      return 0
    }
    if(str.endsWith('.')){
      str=str.substring(0,str.length-1)
    }
    return parseFloat(str)
  }
}

四.总结

    这次完成了对点击记录列表触发的底部面板的逻辑实现,我用Panel容器展现的可滑动面板嵌套实现底部页面的开发,掌握熟悉了Divider用来提供分隔器组件,并且用网格容器Grid组件实现数字键盘。表现处理强大的实用性和可实现性,提高了我对开发工具进一步的熟悉和应用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值