今天,我们接着上次的代码继续进行黑马健康这个APP的开发。
今天预计效果图为:
通过图片我们可以看出整体是一个从上到下的列式布局,所以我们会用到 column容器。我们先进行顶部搜索栏的设计。
一、顶部搜索栏的设计
通过观察我们发现搜索栏是一个搜索框和一个信箱的照片组成。需要用到Search 输入搜索框。
代码为:
import { CommonConstants } from '../../common/constants/CommonConstants'
@Component
export default struct SearchHeader {
build() {
Row({space:CommonConstants.SPACE_6}){
Search({placeholder:'搜索饮食或运动信息'})
.textFont({size:18})
.layoutWeight(1)
Badge({count:1,position:BadgePosition.RightTop,style:{fontSize:12}}) {
Image($r('app.media.ic_public_email'))
.width(24)
}
}
.width(CommonConstants.THOUSANDTH_940) //占屏幕94%
}
}
二、统计卡片设计
统计卡片包括上下两部分,分别为日期、统计卡路里卡片,其中再点击日期时会弹出日期选择窗口,进行选择日期;统计卡路里是可以左右滑动翻页的。
其中,用带两个新的组件,第一个是DatePicker日期选择组件,用于根据指定日期范围创建日期滑动选择器。第二个是Swiper滑块视图容器,提供子组件滑动轮播显示的能力。可通过查阅API文档查看如何使用。
代码为:
//日期选择
import { CommonConstants } from '../../common/constants/CommonConstants'
@CustomDialog
export default struct DatePickDialog {
controller:CustomDialogController
selectedDate:Date=new Date
build() {
Column({space:CommonConstants.SPACE_10}){
//1.日期选择
DatePicker({
start: new Date('2020-01-01'),
end: new Date(),
selected: this.selectedDate
})
.onChange((value: DatePickerResult) => {
this.selectedDate.setFullYear(value.year, value.month, value.day)
})
//2.按钮
Row({space:CommonConstants.SPACE_10}){
Button('取消')
.width(120)
.backgroundColor($r('app.color.light_gray'))
.onClick(()=>this.controller.close())
Button('确定')
.width(120)
.backgroundColor($r('app.color.primary_color'))
.onClick(()=>{
//1.保存日期到全局存储
AppStorage.SetOrCreate('selectedDate',this.selectedDate.getTime())
//2.关闭窗口
this.controller.close()
})
}
}
.padding(CommonConstants.SPACE_10)
}
}
//统计卡片
import { CommonConstants } from '../../common/constants/CommonConstants'
import DateUtil from '../../common/utils/DateUtil'
import CalorieStats from './CalorieStats'
import DatePickDialog from './DatePickDialog'
import NutrientStats from './NutrientStats'
@Component
export default struct StatsCard {
@StorageProp('selectedDate') selectedDate: number =DateUtil.beginTimeOfDay(new Date())
controller:CustomDialogController = new CustomDialogController({
builder:DatePickDialog({selectedDate:new Date(this.selectedDate)})
})
build() {
Column(){
//1.日期信息
Row(){
Text(DateUtil.formatDate(this.selectedDate))
.fontColor($r('app.color.secondary_color'))
Image($r('app.media.ic_public_spinner'))
.width(24)
.fillColor($r('app.color.secondary_color'))
}
.padding(CommonConstants.SPACE_10)
.onClick(()=>this.controller.open())
//2.统计信息
Swiper(){
//2.1热量统计
CalorieStats()
//2.2营养素统计
NutrientStats()
}
.width('100%')
.backgroundColor(Color.White)
.borderRadius(CommonConstants.DEFAULT_16)
.indicatorStyle({selectedColor:$r('app.color.primary_color')})
}
.width(CommonConstants.THOUSANDTH_940)
.backgroundColor($r('app.color.stats_title_bgc'))
.borderRadius(CommonConstants.DEFAULT_20)
}
}
三、记录列表设计
有图可知,这是一个列表,所以我们可以用之前学习的List加上ForEach循环进行设计。由于每个卡片的信息大致一样,所以我们可以只写一个卡片,用ForEach循环遍历进行展示。
代码为:
import { CommonConstants } from '../../common/constants/CommonConstants'
@Extend(Text) function grayText(){
.fontSize(14)
.fontColor($r('app.color.light_gray'))
}
@Component
export default struct RecordList {
build() {
List({space:CommonConstants.SPACE_10}){
ForEach([1,2,3,4,5],(item)=>{
ListItem(){
Column(){
//1.组内标题
Row({space:CommonConstants.SPACE_4}){
Image($r('app.media.ic_breakfast'))
.width(24)
Text('早餐')
.fontSize(18).fontWeight(CommonConstants.FONT_WEIGHT_700)
Text('建议423-592千卡') .grayText()
Blank()
Text('190') .fontSize(14).fontColor($r('app.color.primary_color'))
Text('千卡') .grayText()
Image($r('app.media.ic_public_add_norm_filled'))
.width(20)
.fillColor($r('app.color.primary_color'))
}
.width('100%')
//2.组内记录列表
List(){
ForEach([1,2],(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片').grayText()
}
Blank()
Text('91千卡').grayText()
}
.width('100%')
.padding(CommonConstants.SPACE_6)
}
.swipeAction({end:this.deleteButton.bind(this)})
})
}
.width('100%')
}
.width('100%')
.backgroundColor(Color.White)
.borderRadius(CommonConstants.DEFAULT_18)
.padding(CommonConstants.SPACE_10)
}
})
}
.width(CommonConstants.THOUSANDTH_940)
.height('100%')
.margin({top:10})
}
@Builder deleteButton(){ //滑动删除图标定义
Image($r('app.media.ic_public_delete_filled'))
.width(20)
.fillColor(Color.Red)
.margin(5)
}
}
最后我们的成果图为:
其中记录卡片的具体数据,我们下一期在进行分析。