一.思路分析
本次实验主要是为了完成,当用户点击食物列表后的加号时的弹窗操作,分析该实验可以发现,该页面也是一个Column布局,以及与其他多个row容器的搭配使用。中间的食物数量的实现,主要是Text与Divder的组合使用来实现。对于底部数字键盘的实现,主要是使用Grid组件来实现。对于底部弹窗面板的实现,主要是使用Panel组件,即可滑动面板,一轻量化的内容展示窗口,方便在不同尺寸中进行一个切换。
二.运行截图
三.设计中遇到的问题
如和实现底部弹窗面板的实现:
解决方法:
使用Panel组件来实现该功能,Panel:即可滑动面板,一轻量化的内容展示窗口,方便在不同尺寸中进行一个切换。Panel组件在使用时,需要指定一个布尔类型的参数,用力啊控制,该面板是显示还是隐藏,true为显示false为隐藏。通过Paneltype属性可以实现控制诸多功能,包括全屏展示效果,以及内容临时展示区的操作等。
数字键盘面板的实现:
使用Grid网格容器来实现数字键盘功能,Grid,即网格容器,由行和列分割单元格所组成,可以通过指定项目所在的单元格做出各种各样的布局。该组件使用时需要传递一个Scroller,即滚动条控制器,但由于本实验数字键盘内容过少,因此可以不使用该功能,随后,可以使用网格容器的columnsTemplate属性来设置当前网格布局列的数量,需要注意的是,当设置‘0fr’时,该列的列宽为0,不显示GridItem,使用RowTemplate属性来设置当前网格布局行的数量,随后使用ClickDetele来对用户输入的数字进行一个判断与拼接,从而实现数字键盘的实现。
四.代码
import { CommonConstants } from '../common/constants/CommonConstants'
import router from '@ohos.router'
import ItemList from '../view/item/ItemList'
import ItemPanelHeader from '../view/item/ItemPanelHeader'
import ItemCard from '../view/item/ItemCard'
import NumberKeyboard from '../view/item/NumberKeyboard'
@Entry
@Component
struct ItemIndex {
@State amount: number = 1
@State showPanel: boolean = false
@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)
// 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)
}
}
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.indexOf('.')
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)
}
}
五.总结
本次实验主要完成了底部Panel以及数字键盘的实现,对于用户点击食物后的弹窗效果,主要是通过,Panel实现,Panel即可滑动面板,一轻量化的内容展示窗口,方便在不同尺寸中进行一个切换随后便可以在其中定义面板中所需要的内容,对于数字键盘的实现,则是使用了Grid网格组件,通过该组件的属性,来控制行以及列的数量,随后使用ClickDetele来对用户输入的数字进行一个判断与拼接,从而达到数字选择面板的效果。