鸿蒙应用开发(ArkTS)—健康生活应用解读(三)
《色彩心理学在健康生活中的应用》:解读生活艺术与健康的关系 #生活乐趣# #生活艺术# #健康生活艺术# #健康生活书籍#
关于上一篇文章
鸿蒙应用开发(ArkTS)—健康生活应用解读(二)-CSDN博客https://blog.csdn.net/m0_73005007/article/details/139776594?spm=1001.2014.3001.5501
本文章继解读(二),进行第二部分主页面的实现,包括首页和饮食记录部分,我将分两部分解读UI部分
如果大家有什么建议或者问题的话都可以给我留言,24H之内我肯定回复
UI设计(一)
首页使用tabs组件实现首页视图内容的切换,需要与tabbar和tabcontent一起使用
tabs组件的定义
Tabs()
{
Tabcontent(){
Text('内容1')}
.tabBar('标题1”)
Tabcontent(){
Text('内容2')}
.tabBar('标照2')
}
.width('100%')
.height('100%')
默认的tabBar位置在顶部,可以通过 barposition改变( barposition.end或者 barposition.start)
.vertical()可以控制Tabs的水平或者纵向,在纵向布局(false)中,end代表在右侧
关于自定义tabbar样式,可以使用@Builder进行构造
@Builder TabBuilder(title:string,image:ResourceStr,index:number){
Column({space:4)){
Image(image)
Text(title)
}
.justifycontent(FlexAlign.Center)
}
此处的index为角标,在样式变化时使用
关于样式的变化,可以定义一个状态变量接收角标,然后进行改变
@State currentIndex: number=0
添加onchange接收角标
.onChange(index=>this.currendIndex=index)
判断是否为当前图标,如果是则改变
@Builder TabBuilder(title:string,image:ResourceStr,index:number){
Column({space:4)){
Image(image).fillcolor(this.currentIndex===index?color.blue:color.gray)
Text(title).fillcolor(this.currentIndex===index?color.blue:color.gray)
}
.justifycontent(FlexAlign.Center)
}
使用代码如下
饮食记录部分首页:
true
首页的布局从上到下依次是由搜索栏(search),卡片(datepicker和swiper)和食物列表(List)
在这部分中,使用了两个新的组件
search:搜索框组件,适用于浏览器的搜索内容输入框等应用场景,参数如下,来自官方API文档
关于Badge:可以附加在单个组件上用于信息标记的容器组件。
参数名
参数类型
必填
默认值
参数描述
count
number
是
-
设置提醒消息数。
说明:
小于等于0时不显示信息标记。
position
BadgePosition
否
BadgePosition.RightTop
设置提示点显示位置。
maxCount
number
否
99
最大消息数,超过最大消息时仅显示maxCount+。
style
BadgeStyle
是
-
Badge组件可设置样式,支持设置文本颜色、尺寸、圆点颜色和尺寸。
Badge(value: {value: string, position?: BadgePosition, style: BadgeStyle})
根据字符串创建标记组件。
从API version 9开始,该接口支持在ArkTS卡片中使用。
参数名
参数类型
必填
默认值
参数描述
value
string
是
-
提示内容的文本字符串。
position
BadgePosition
否
BadgePosition.RightTop
设置提示点显示位置。
style
BadgeStyle
是
-
Badge组件可设置样式,支持设置文本颜色、尺寸、圆点颜色和尺寸。
从API version 9开始,该接口支持在ArkTS卡片中使用。
名称
描述
RightTop
圆点显示在右上角。
Right
圆点显示在右侧纵向居中。
Left
圆点显示在左侧纵向居中。
从API version 9开始,该接口支持在ArkTS卡片中使用。
名称
类型
必填
默认值
描述
color
ResourceColor
否
Color.White
文本颜色。
fontSize
number | string
否
10
文本大小。
单位:vp
说明:
不支持设置百分比。
badgeSize
number | string
否
16
Badge的大小。不支持百分比形式设置。当设置为非法值时,按照默认值处理。
单位:vp
badgeColor
ResourceColor
否
Color.Red
Badge的颜色。
代码实现
index.ets
import { CommonConstants } from '../common/constants/CommonConstants'
@Entry
@Component
struct Index {
@State currentIndex: number = 0
selectColor(index: number) {
return this.currentIndex === index ? $r('app.color.primary_color') : $r('app.color.gray')
}
@Builder TabBarBuilder(title: String , image: ResourceStr, index: number) {
Column({ space: CommonConstants.SPACE_8 }) {
Image(image)
.width(22)
.fillColor(this.selectColor(index))
Text('title')
.fontSize(14)
.fillColor(this.selectColor(index))
}
}
build() {
Tabs({barPosition: BarPosition.End}){
TabContent(){
Text('饮食记录')
}
.tabBar(this.TabBarBuilder('首页',$r('app.media.P1'),0))
TabContent(){
Text('社区')
}
.tabBar(this.TabBarBuilder('社区',$r('app.media.P1'),1))
TabContent(){
Text('我的')
}
.tabBar(this.TabBarBuilder('我的',$r('app.media.P1'),2))
}
.width('100%')
.height('100%')
.onChange(index=>this.currentIndex=index)
}
}
ItemList.ets
import { CommonConstants } from '../common/constants/CommonConstants'
@Component
struct ItemList {
build() {
Tabs() {
TabContent() {
}
.tabBar('全部')
}
.width(CommonConstants.THOUSANDTH_900)
.height('100%')
}
}
CalorieStats.ets
import { CommonConstants } from '../../common/constants/CommonConstants'
@Component
export default struct CalorieStats {
@Prop intake: number
@Prop expend: number
recommend: number = CommonConstants.RECOMMEND_CALORIE
remainCalorie() {
return this.recommend - this.intake + this.expend
}
build() {
Row({ space: CommonConstants.SPACE_6 }) {
// 1.饮食摄入
this.StatsBuilder({ label: '饮食摄入', value: this.intake })
// 2.还可以吃
Stack() {
// 2.1.进度条
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.统计数据
this.StatsBuilder({ label: '还可以吃', value: this.remainCalorie(), tips: `推荐${this.recommend}` })
}
// 3.运动消耗
this.StatsBuilder({ label: '运动消耗', value: this.expend })
}
.width('100%')
.justifyContent(FlexAlign.SpaceEvenly)
.padding({ top: 30, bottom: 35 })
}
@Builder StatsBuilder($$: {
label: string,
value: number,
tips?: string
}) {
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)
if ($$.tips) {
Text($$.tips)
.fontSize(12)
.fontColor($r('app.color.light_gray'))
}
}
}
}
DatePickDialog.ets
import { CommonConstants } from '../../common/constants/CommonConstants'
@CustomDialog
export default struct DatePickDialog {
controller: CustomDialogController
selectedDate: Date = new Date()
build() {
Column({space:CommonConstants.SPACE_12}){
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)
})
Row({space:CommonConstants.SPACE_12}){
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_12)
}
}
RecordIndex.ets
import { CommonConstants } from '../../common/constants/CommonConstants'
@Component
export default struct NutrientStats {
@Prop carbon: number
@Prop protein: number
@Prop fat: number
recommendCarbon: number = CommonConstants.RECOMMEND_CARBON
recommendProtein: number = CommonConstants.RECOMMEND_PROTEIN
recommendFat: number = CommonConstants.RECOMMEND_FAT
build() {
Row({space: CommonConstants.SPACE_6}){
this.StatsBuilder({
label: '碳水化合物',
value: this.carbon,
recommend: this.recommendCarbon,
color: $r('app.color.carbon_color')
})
this.StatsBuilder({
label: '蛋白质',
value: this.protein,
recommend: this.recommendProtein,
color: $r('app.color.protein_color')
})
this.StatsBuilder({
label: '脂肪',
value: this.fat,
recommend: this.recommendFat,
color: $r('app.color.fat_color')
})
}
.width('100%')
.justifyContent(FlexAlign.SpaceEvenly)
.padding({top: 30, bottom: 35})
}
@Builder StatsBuilder($$:{label: string, value: number, recommend: number, color: ResourceStr}){
Column({space: CommonConstants.SPACE_6}){
Stack(){
Progress({
value: $$.value,
total: $$.recommend,
type: ProgressType.Ring
})
.width(95)
.style({strokeWidth: CommonConstants.DEFAULT_6})
.color($$.color)
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_600)
}
}
Text(`${$$.label}(克)`)
.fontSize(12)
.fontColor($r('app.color.light_gray'))
}
}
}
SearchHeader.ets
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.P1'))
.width(24)
}
}
.width(CommonConstants.THOUSANDTH_940)
}
}
StatsCard.ets
// @ts-nocheck
import BreakpointType from '../../common/bean/BreanpointType'
import BreakpointConstants from '../../common/constants/BreakpointConstants'
import { CommonConstants } from '../../common/constants/CommonConstants'
import DateUtil from '../../common/utils/DateUtil'
import CalorieStats from './CalorieStats'
import DatePickDialog from './DatePickDialog'
@Component
export default struct StatsCard {
@StorageProp('selectedDate') selectedDate: number = DateUtil.beginTimeOfDay(new Date())
@StorageProp('currentBreakpoint') currentBreakpoint: string = BreakpointConstants.BREAKPOINT_SM
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.P1'))
.width(20)
.fillColor($r('app.color.secondary_color'))
}
.padding(CommonConstants.SPACE_8)
.onClick(() => this.controller.open())
// 2.统计信息
Swiper(){
// 2.1.热量统计
CalorieStats({intake: this.info.intake, expend: this.expend})
// 2.2.营养素统计
NutrientStats({carbon: this.info.carbon, protein: this.info.protein,fat: this.info.fat})
}
.width('100%')
.backgroundColor(Color.White)
.borderRadius(CommonConstants.DEFAULT_18)
.indicatorStyle({selectedColor: $r('app.color.primary_color')})
.displayCount(new BreakpointType({
sm: 1,
md: 1,
lg: 2
}).getValue(this.currentBreakpoint))
}
.width(CommonConstants.THOUSANDTH_940)
.backgroundColor($r('app.color.stats_title_bgc'))
.borderRadius(CommonConstants.DEFAULT_18)
}
}
网址:鸿蒙应用开发(ArkTS)—健康生活应用解读(三) https://www.yuejiaxmz.com/news/view/736349
相关内容
鸿蒙HarmonyOS应用开发健康生活应用(ArkTS)
鸿蒙(HarmonyOS)应用开发——健康生活应用(4)
鸿蒙应用
基于OpenHarmony开发的健康生活应用(ArkTS)
【harmonyOS开发】健康生活应用
鸿蒙应用开发教程第02期:完整开发流程,速戳!
鸿蒙原生版金融理财应用全面接入安全能力与统一认证体系,超80款已上架
AppGallery Awards 年度影响力应用与游戏发布,我们看到了鸿蒙应用生态的新趋势
便捷生活场景再扩张!叮咚买菜启动鸿蒙原生应用开发