食物列表底部Panel
// src/main/ets/pages/ItemIndex.ets
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'
@Extend(Button) function panelButtonStyle(){
.width(120)
.type(ButtonType.Normal)
.borderRadius(6)
}
@Entry
@Component
struct ItemIndex {
@State showPanel: boolean = false
@State amount: number = 1
@State value: string = ''
onPanelShow(){
this.amount = 1
this.value = ''
this.showPanel = true
}
build() {
Column() {
// 1.头部导航
this.Header()
// 2.列表
ItemList({showPanel: this.onPanelShow.bind(this)})
.layoutWeight(1) // 这里注意,ItemList作为Panel的容器,必须要有高度
// 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('取消')
.panelButtonStyle()
.backgroundColor($r('app.color.light_gray'))
.onClick(() => this.showPanel = false)
Button('提交')
.panelButtonStyle()
.backgroundColor($r('app.color.primary_color'))
.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)
Blank()
Text('早餐').fontSize(18).fontWeight(CommonConstants.FONT_WEIGHT_600)
}
.width(CommonConstants.THOUSANDTH_940)
.height(32)
}
}
// src/main/ets/view/item/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(){
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') // 分成3列
.columnsGap(8) // 列间距
.rowsGap(8) // 行间距
.padding(8)
.margin(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)){
// 非法输入
// firstIndex !== lastIndex 说明有两个及以上个小数点
// lastIndex != -1 && lastIndex < val.length - 2 有小数点,且小数长度不大于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
}
// 如果最后有一个小数点,比如这样的 23. 就把最后的小数点去掉
if(str.endsWith('.')){
str = str.substring(0, str.length - 1)
}
return parseFloat(str)
}
}
在创建数据模型后,可实现数据动态化,页面显示数据更灵活方便。