好的我们上篇文章已经完成了食物列表页面UI的基本设计,本篇文章要实现当点击加号按钮时将弹出一个面板,面板中显示食物的详细信息
还是老规矩我们先对页面的布局进行分析
一、分析布局
很容易看出整个面板的布局时一个列式布局,其中每一个元素又都是一些行式布局也就是好多个row在一个column里,那么我们来从上到下的分析一下每一行的布局
首先第一行是一个文本加一个按钮小图标,点击图标会出现弹窗
第二行就是一个单纯的图片
第三行就是一个文本
第四行就是很多文本也就是食物的详细信息
第五行是一个文本加下划线
第六行是一个自制键盘
第七行是两个按钮
二、关键技术
1.Panel面板
Panel组件是一个可滑动面板,提供一种轻量的内容展示窗口,方便在不同尺寸中切换
我们来看一下它的API文档,注意Panel它所在容器的高度以及内元素的高度必须是一个固定的
三、正式开发
在正式开发前我建议你回顾一下上篇文章的内配合起来看会更容易明白我在说什么
1.基础声明
首先我们在列表主页来声明Panel面板和它的状态变量
// 3.底部面板
Panel(this.showPanel)
@State showPanel: boolean = false
由于我们底部面板出现的时机是当我们点击列表的加号按钮时从下往上出现,所以需要给列表的每个项加上点击事件,并且我们由于想要控制父组件中的元素弹出所以需要声明一个函数当父组件调用时来覆盖这个声明,所以我们在ItemList中完成这些操作
showPanel: () => void
@Builder TabContentBuilder(){
List({space:CommonConstants.SPACE_10}){
ForEach([1,2,3,4,5,6,7,8], (item) => {
ListItem(){
Row({space: CommonConstants.SPACE_6}){
Image($r('app.media.toast')).width(50)
Column({space: CommonConstants.SPACE_4}){
Text('全麦土司').fontWeight(CommonConstants.FONT_WEIGHT_500)
Text('1片').fontSize(14).fontColor($r('app.color.light_gray'))
}
Blank()
Image($r('app.media.ic_public_add_norm_filled'))
.width(18)
.fillColor($r('app.color.primary_color'))
}
.width('100%')
.padding(CommonConstants.SPACE_6)
}
.onClick(() => this.showPanel())//点击事件
})
}
.width('100%')
.height('100%')
接着我们在列表主页中声明一个函数,里面写当面板展示时需要做的事情,也就是当按钮被点击后底部面板就会出现
onPageShow(){
this.showPanel = true
}
2.面板样式
面板可以正常显示后,接下来就开始对面板进行操作
根据API文档内提供的信息我们很容易可以设置好面板的样式,完成后我们加一个关闭按钮先看一下效果
// 3.底部面板
Panel(this.showPanel) {
Button('关闭').onClick(()=>this.showPanel = false)
}
.mode(PanelMode.Full)//全部显示
.dragBar(false)//不可调整高度
.backgroundMask($r('app.color.light_gray'))//蒙版颜色浅灰
.backgroundColor(Color.White)//背景颜色
我们可以看到面板的基础样式已经完成了,那么接下来就是面板内容了
3.面板内容
面板的内容也就是我们在分析布局中说的那些内容,数字键盘我们下一篇文章再说(先整点好整的)
①头部日期文本加弹窗
还是一样我们来新建一个ets当作组件来调用,提高一下代码的可读性
@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)
}
}
}
由于黑马这块就直接省略了,这个弹窗跟前几篇文章提到过的DatePicker日期选择器组件是基本上相似的,并且作者这会也是在赶作业加期末复习,所以在这里就偷个懒跟黑马一样放个图片得了,有想完善的同学可以继续加油
②食物信息
同样定义一个组件
@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.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('热量',91.0)
this.NutrientInfo('热量',91.0)
this.NutrientInfo('热量',91.0)
this.NutrientInfo('热量',91.0)
}
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.toFixed(1)).fontSize(18).fontWeight(CommonConstants.FONT_WEIGHT_700)
}
}
}
四、最终效果
经过我们的开发,食物列表的Panel面板是属于完成了一大部分了,那么下篇文章我们来开发数字键盘,由于我们这个输入只要求是数字类型的,与其防止用户去输入一些乱七八糟的东西不如直接给他提供一个数字键盘只能输入数字
OK,我们下篇文章接着讲,我们这里附上黑马程序员食物列表底部Panel的视频链接,文章配合视频更好理解哦。