一、顶部搜索栏
1、大概布局
1.2重新创建新的组件文件
RecorIndex文件时饮食记录主界面,而SearchHeader文件时顶部搜索栏的组件
2、代码
SearchHeade组件的代码
// 导入CommonConstants,它可能包含一些在UI构建中会用到的通用常量。
import { CommonConstants } from '../../common/constants/CommonConstants'
// 使用@Component装饰器标记这个结构体是一个组件。
@Component
export default struct SearchHeader {
// build函数定义了组件的构建逻辑。
build() {
// 使用Row函数创建一个水平布局的行,space属性设置组件间的间距。
Row({ space: CommonConstants.SPACE_6 }) {
// 在行内添加一个Search组件,用于创建搜索框。
// 设置placeholder属性为提示文本。
Search({ placeholder: '搜索饮食或运动信息' })
// 使用textFont方法设置搜索框内文字的字体大小。
.textFont({ size: 18 })
// 使用layoutWeight方法设置Search组件在剩余空间中的权重,使其可以根据父容器宽度自适应。
.layoutWeight(1)
// 在行内添加一个Badge组件,用于显示徽章(通常用于显示未读消息数量)。
// 设置count属性为徽章上的数字,position属性定义徽章的位置。
// style属性定义徽章的样式,这里设置了字体大小。
Badge({ count: 3, position: BadgePosition.RightTop, style: { fontSize: 14 } }) {
// 在Badge组件内部添加一个Image组件,用于显示徽章旁边的图标。
Image($r('app.media.ic_public_email'))
// 设置Image组件的宽度。
.width(24)
}
}
// 设置组件的宽度为CommonConstants.THOUSANDTH_940定义的值。
.width(CommonConstants.THOUSANDTH_940)
}
}
3.运行效果
二、统计卡片
1、概述
创建新的组件StatsCard(),用与调用CalorieStats(热量统计)和NutrientStats(营养素统计)两个不同的组件,以及被RecordIndex组件调用
首先是统计卡片的组件StatsCard,有存储日期查看某一天的日期的作用,主要用于调用两个不同的子组件
1.1代码为:
// 导入必要的模块和常量
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装饰器定义一个结构体StatsCard,表示一个统计卡片组件
@Component
export default struct StatsCard {
// 使用@StorageProp装饰器定义一个存储属性selectedDate,用于存储选中的日期
// 初始值为当前日期的开始时间
@StorageProp('slectedDate') selectedDate: number = DateUtil.beginTimeOfDay(new Date());
// 初始化一个自定义对话框控制器,用于管理日期选择对话框
controller: CustomDialogController = new CustomDialogController({
builder: DatePickDialog({selectedDate: new Date(this.selectedDate)})
});
// build函数定义了组件的构建逻辑
build() {
// 使用Column函数创建一个垂直布局的列
Column() {
// 1. 日期信息
Row() {
// 在行中添加文本组件,显示格式化的日期
Text(DateUtil.formatDate(this.selectedDate))
.fontColor($r('app.color.secondary_color')); // 设置文本颜色
// 在行中添加图片组件,用作日期选择的图标
Image($r('app.media.ic_public_spinner'))
.width(20) // 设置图片宽度
.fillColor($r('app.color.secondary_color')); // 设置图片填充颜色
}
.padding(CommonConstants.SPACE_10) // 设置内边距
.onClick(() => this.controller.open()); // 设置点击事件,打开日期选择对话框
// 2. 统计信息
// 使用Swiper组件创建一个滑动视图,包含热量统计和营养素统计
Swiper() {
// 2.1 热量统计组件
CalorieStats();
// 2.2 营养素统计组件
NutrientStats();
}
.width('100%') // 设置Swiper组件宽度为100%
.backgroundColor(Color.White) // 设置Swiper组件背景颜色为白色
.borderRadius(CommonConstants.DEFAULT_18) // 设置Swiper组件的圆角大小
.indicatorStyle({ // 设置Swiper组件的分页指示器样式
selectedColor: $r('app.color.primary_color') // 选中项的颜色
});
}
// 设置外层Column组件的宽度、背景颜色和圆角
.width(CommonConstants.THOUSANDTH_940)
.backgroundColor($r('app.color.stats_title_bgc'))
.borderRadius(CommonConstants.DEFAULT_18);
}
}
1.2运行结果
2、概述
CalorieStats(热量统计)组件用于统计运动消耗,饮食摄入,还可以吃多少等数据,并且用进度条表示。进度条通过属性传递配置给进度条,如 value
、total
和 type,其中value
和 total
属性绑定到数值上,表示当前进度和最大进度。ProgressType
枚举定义了进度条的不同类型或形状,如线性(linear)或环形(ring)。
2.1代码:
// 导入CommonConstants,它可能包含一些在UI构建中会用到的通用常量。
import { CommonConstants } from '../../common/constants/CommonConstants';
@Component
// 使用@Component装饰器定义一个结构体CalorieStats,表示一个卡路里统计组件。
export default struct CalorieStats {
// 定义摄入卡路里的变量intake并初始化为192。
intake: number = 192;
// 定义消耗卡路里的变量expend并初始化为150。
expend: number = 150;
// 定义推荐的每日卡路里摄入量,使用CommonConstants中的常量。
recommend: number = CommonConstants.RECOMMEND_CALORIE;
// remainCalorie函数计算剩余的卡路里摄入量。
remainCalorie() {
// 返回推荐摄入量减去已摄入的量再加上消耗的量。
return this.recommend - this.intake + this.expend;
}
// build函数定义了组件的构建逻辑。
build() {
// 使用Row函数创建一个水平布局的行,space属性设置组件间的间距。
Row({ space: CommonConstants.SPACE_6 }) {
// 1. 调用StatsBuilder函数构建饮食摄入部分。
this.StatsBuilder('饮食摄入', this.intake);
// 2. 使用Stack布局构建还可以吃部分,Stack用于层叠布局。
Stack() {
// 2.1. 调用Progress组件创建一个进度环,显示已摄入的卡路里占推荐量的百分比。
Progress({
value: this.intake,
total: this.recommend,
type: ProgressType.Ring // 设置进度类型为环状。
})
.width(120) // 设置进度环的宽度。
.style({ strokeWidth: CommonConstants.DEFAULT_10 }) // 设置进度环的描边宽度。
.color($r('app.color.primary_color')); // 设置进度环的颜色。
// 2.2. 再次调用StatsBuilder函数构建还可以吃部分的统计数据和提示。
this.StatsBuilder('还可以吃', this.remainCalorie(), `推荐${this.recommend}`);
}
// 3. 调用StatsBuilder函数构建运动消耗部分。
this.StatsBuilder('运动消耗', this.expend);
}
// 设置Row组件的宽度、内容对齐方式和内边距。
.width('100%')
.justifyContent(FlexAlign.SpaceEvenly) // 内容在主轴上的分布方式为均匀分布。
.padding({ top: 30, bottom: 35 }); // 设置上内边距为30,下内边距为35。
}
// 使用@Builder装饰器定义StatsBuilder函数,用于构建统计信息。
// 它接受标签label、数值value和可选的提示信息tips。
@Builder StatsBuilder(label: string, value: number, tips?: string) {
// 使用Column函数创建一个垂直布局的列。
Column({ space: CommonConstants.SPACE_6 }) {
// 添加标签文本。
Text(label)
.fontColor($r('app.color.gray')) // 设置文本颜色。
.fontWeight(CommonConstants.FONT_WEIGHT_600); // 设置文本的字重。
// 添加数值文本,并格式化为整数。
Text(value.toFixed(0))
.fontSize(20) // 设置文本的字号。
.fontWeight(CommonConstants.FONT_WEIGHT_700); // 设置文本的字重。
// 如果提供了提示信息tips,添加提示文本。
if (tips) {
Text(tips)
.fontSize(12) // 设置文本的字号。
.fontColor($r('app.color.light_gray')); // 设置文本颜色。
}
}
}
}
2.2运行结果
3. 概述
NutrientStats(营养素统计)与CalorieStats(热量统计)类似,所使用到的知识点相差不大
3.1代码
// 导入CommonConstants,它可能包含一些在UI构建中会用到的通用常量。
import { CommonConstants } from '../../common/constants/CommonConstants';
@Component
// 使用@Component装饰器定义一个结构体NutrientStats,表示一个营养素统计组件。
export default struct NutrientStats {
// 定义当前摄入的营养素数量变量。
carbon: number = 23;
protein: number = 9;
fat: number = 5;
// 定义推荐摄入的营养素数量常量。
recommendCarbon: number = CommonConstants.RECOMMEND_CARBON;
recommendProtein: number = CommonConstants.RECOMMEND_PROTEIN;
recommendFat: number = CommonConstants.RECOMMEND_FAT;
// build函数定义了组件的构建逻辑。
build() {
// 使用Row函数创建一个水平布局的行,space属性设置组件间的间距。
Row({ space: CommonConstants.SPACE_6 }) {
// 为每种营养素调用StatsBuilder函数构建统计信息。
this.StatsBuilder(
'碳水化合物', // 营养素名称
this.carbon, // 当前摄入量
this.recommendCarbon, // 推荐摄入量
$r('app.color.carbon_color') // 进度环的颜色
);
this.StatsBuilder(
'蛋白质',
this.protein,
this.recommendProtein,
$r('app.color.protein_color')
);
this.StatsBuilder(
'脂肪',
this.fat,
this.recommendFat,
$r('app.color.fat_color')
);
}
// 设置Row组件的宽度、内容对齐方式和内边距。
.width('100%')
.justifyContent(FlexAlign.SpaceEvenly) // 内容在主轴上的分布方式为均匀分布。
.padding({ top: 30, bottom: 35 }); // 设置上内边距为30,下内边距为35。
}
// 使用@Builder装饰器定义StatsBuilder函数,用于构建单个营养素的统计信息。
// 它接受营养素名称label、当前摄入量value、推荐摄入量recommend和进度环颜色color。
@Builder StatsBuilder(label: string, value: number, recommend: number, color: ResourceStr) {
// 使用Column函数创建一个垂直布局的列。
Column({ space: CommonConstants.SPACE_6 }) {
Stack() {
// 使用Progress组件创建一个环形进度条,表示当前摄入量相对于推荐量的进度。
Progress({
value: value,
total: recommend,
type: ProgressType.Ring // 设置进度类型为环形。
})
.width(95) // 设置进度环的宽度。
.style({ strokeWidth: CommonConstants.DEFAULT_6 }) // 设置进度环的描边宽度。
.color(color); // 设置进度环的颜色。
// 在同一Stack中,使用Column布局构建文本信息。
Column({ space: CommonConstants.SPACE_6 }) {
Text('摄入推荐') // 显示“摄入推荐”文本。
.fontSize(12)
.fontColor($r('app.color.gray')); // 设置文本颜色。
// 显示当前摄入量和推荐摄入量。
Text(`${value.toFixed(0)}/${recommend.toFixed(0)}`)
.fontSize(18)
.fontWeight(CommonConstants.FONT_WEIGHT_700); // 设置文本的字重。
}
}
// 显示营养素名称和单位。
Text(`${label}(克)`)
.fontSize(12)
.fontColor($r('app.color.light_gray')); // 设置文本颜色。
}
}
}
2.2运行结果
三、纪录列表
1.代码
// 导入CommonConstants,可能包含一些在UI构建中会用到的通用常量。
import { CommonConstants } from '../../common/constants/CommonConstants';
// 定义一个扩展函数grayText,用于设置文本样式为灰色和特定字号。
@Extend(Text)
function grayText() {
.fontSize(14) // 设置字体大小为14。
.fontColor($r('app.color.light_gray')) // 设置字体颜色为应用定义的浅灰色。
}
@Component
// 使用@Component装饰器定义一个结构体RecordList,表示一个记录列表组件。
export default struct RecordList {
build() {
// 使用List函数创建一个列表,space属性设置列表项之间的间距。
List({ space: CommonConstants.SPACE_10 }) {
// 使用ForEach遍历数组[1,2,3,4,5],为每个项创建一个列表项。
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)
// 使用之前定义的grayText函数设置文本样式。
Text('建议432-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函数创建一个内嵌列表。
List() {
// 使用ForEach遍历数组[1, 2],为每个项创建一个列表项。
ForEach([1, 2], (item) => {
ListItem() {
Row({ space: CommonConstants.SPACE_4 }) {
// 添加图标、文本列和空白组件,设置相应的样式和属性。
Image($r('app.media.toast')).width(50)
Column({ space: CommonConstants.SPACE_4 }) {
Text('全麦吐司').fontWeight(CommonConstants.FONT_WEIGHT_500)
Text('1片').grayText()
}
Blank()
// 使用grayText函数设置文本样式。
Text('91千卡').grayText()
}
.width('100%')
.padding(CommonConstants.SPACE_6)
}
// 为列表项添加滑动删除动作。
.swipeAction({ end: this.deleteButton.bind(this) })
})
}
}
.width('100%')
.backgroundColor(Color.White)
.borderRadius(CommonConstants.DEFAULT_18)
.padding(CommonConstants.SPACE_12)
}
})
}
.width(CommonConstants.THOUSANDTH_940) // 设置列表组件的宽度。
.height('100%') // 设置列表组件的高度。
.margin({ top: 10 }) // 设置上边距。
}
// 使用@Builder装饰器定义deleteButton函数,用于创建删除按钮的UI。
@Builder deleteButton() {
Image($r('app.media.ic_public_delete_filled')) // 设置删除图标。
.width(20) // 设置图标宽度。
.fillColor(Color.Red) // 设置图标填充颜色为红色。
.margin(5) // 设置图标外边距。
}
}