当前位置:   article > 正文

期末项目实战:基于鸿蒙ArkTs语言的健康检测App主页面开发_arkts 项目

arkts 项目

2.首页设计

2.1首页的页面总体布局

底部为一个导航栏,导航栏上方是需要展示的内容,当我们点击导航栏的不同的项的时候导航栏上方的内容也会随之发生改变

使用Tabs组件来实现上述逻辑设计

鸿蒙开发的Tabs组件是一种用户界面(UI)组件,它是一个可以容纳多个选项卡的容器组件。每个选项卡通常包含一个面板和一个标签,用户可以通过点击标签来切换面板。

这种组件的作用主要有以下几点:

  1. 切换选项卡:用户可以通过点击标签来切换显示面板。
  2. 激活状态显示:当前选中的标签会呈现激活状态,使用户清楚地知道他们当前所在的选项卡。
  3. 自定义选项卡内容:用户可以自定义选项卡内容,如图片、文本、图标等,以增强页面的可读性和可用性。
  4. 加载延迟:如果页面需要加载大量数据或内容,Tabs组件可以通过延迟加载未激活的面板来提升页面性能。
  5. 提高页面的可维护性和可用性:通过展示多个相关但又不需要同时展示的数据集合或功能集合。

        此外,Tabs组件还支持一些特定的布局和行为,例如基本布局、侧边导航、导航效果等,这些特性允许开发者根据应用的具体需求定制Tabs组件的行为和外观。

引用来源:

鸿蒙HarmonyOS实战-ArkUI组件(Tabs)

鸿蒙Harmony应用开发—ArkTS声明式开发(容器组件:Tabs)

        本次实验的Tabs实现方式主要包含两部分内容:TabBar(导航条)和TabContent(内容)

默认的TabBar就是文本的形式,如果想传入图片参数可以使用@Builder构造器来实现

        在其中,用户可以自定义TabBar的样式,只需要将定义的样式传入TabBar的括号中即可,因为每个标签的文字和图片都不相同,所以在此定义为变量的形式,可以让用户进行传参,方便用户的自定义。

定义完@Builder之后,可以直接在Tab()方法中调用.tabBar方法并传入参数,实现用户的自定义

        现在仍存在一个问题,使用自定义样式之后,系统只会判断是否点击,点击后的图片的交互(高亮)并没有完成,系统不知道你目前切换到了哪一个Bar,从而无法完成切换。解决方法是新增一个状态变量@state currentIndex:number =0 专门用来记录当前切换到了哪个bar。

那么如何来得知到该状态变量的值呢?

下列有两种解决方法:

        在事件处理函数中访问状态:当用户与组件交互时(例如点击事件),你可以在事件处理函数中访问状态变量。

        可以在上方的Tabs方法中添加onChange事件,当用户点击标签时,onChange事件就会被触发,触发过程中角标的值会被传递,用户只需要记录到状态变量中即可,记录到的前提是要在渲染图片或者文本的时候进行判断,判断当前Index是否和我的Index一样

使用第二种方法调用onChange判断用户点击的是什么

使用第二种方法后判断角标是否相同,这样被切中的标签就会变成蓝色高亮,否则为灰色

3.首页开发

界面效果如下:

3.1.初始tabBar搭建

利用tabBar完成初始页面的搭建,但是目前仍有如下问题

1.标签全部在上面,没有到界面的下方

2.标签部分全部是文字,没有完成图片的自定义导入

3.点击标签时没有页面的交互,如果不看出现的内容则页面没有任何变化,缺乏交互性

解决

1.将tabBar中插入定位即可完成标签在页面底部的定位

2.使用@Builder装饰器定义页面UI的基本结构,传入参数,在必要的时候直接调用相关的资源,完成界面的自定义

通过声明装饰器以及调用,完成界面的自定义。

3.通过构建onChange点击事件,并且在构造器中完成对颜色的判断即可让用户知道自己现在跳转到了哪个标签

3.2页面搜索栏设计

3.2.1首页UI设计原理

页面由三部分组成,上部分为一个搜索框和图片组件,中间的部分是一个日期选择器(DatePicker)和一个Swiper组件,可以进行左右轮换,滑动时可以展示其他的信息二者可以进行来回切换,下方部分是信息的显示部分,核心是一个List列表

3.2.2首页UI开发

为了减少代码的复杂度,可以另外设计一个组件,只需要在Index中对应的位置应用就可以了,可以在view中新建一个record目录用来存放组件,与记录有关的所有的组件都可以放入其中

新增的RecoardIndex.ets文件,用来存放相应的组件。由于图片的三部分第一部分为头部搜索栏,所以可以将头部搜索栏单独生成一个文件,在RecoardIndex中直接调用他的方法即可,我们先生成一个SearchHeader.ets文件,用来存放头部搜索栏的相关文件,并且设置头部搜索栏的组件样式、数字角标与图片等

头部角标的文件源码如下:

Badge:鸿蒙操作系统(HarmonyOS)中的Badge组件是一种用于显示数字或文本标记的容器组件,它可以附加在应用界面的单个组件上,用于提醒用户有关信息的数量或状态。

3.2.1.1参数配置
  • count:设置提醒消息数,小于等于0时不显示信息标记。
    • position:设置提示点显示位置,默认为BadgePosition.RightTop。
    • maxCount:最大消息数,超过时显示maxCount+,默认值为99。
    • style:设置Badge组件的样式,包括文本颜色、尺寸、圆点颜色和尺寸等。
  1. BadgePosition枚举:定义了Badge的位置,如RightTop(右上角)、Right(右侧纵向居中)、Left(左侧纵向居中)。
  2. BadgeStyle对象:定义了Badge的样式属性,包括文本颜色、大小、Badge的大小和颜色等。
  3. 样式属性:
    • color:文本颜色,默认为白色。
    • fontSize:文本大小,默认为10vp。
    • badgeSize:Badge的大小,默认为16vp。
    • badgeColor:Badge的颜色,默认为红色。
  1. 通用属性和事件:Badge组件支持通用属性和事件,允许开发者根据需要进行定制。
  2. 使用场景:Badge组件常用于通知用户有未读消息、更新、提醒等,比如在图标或列表项上显示未读消息的数量。

相关文件为:

【愚公系列】2022年01月 华为鸿蒙OS-04-容器组件(badge、dialog、div)(JS开发版)

【鸿蒙软件开发】ArkTS容器组件之Badge

鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之Badge组件

在图片中,首先调用原有的Search组件来定义该页面的头部,Pleaceholder用来输入默认信息,是组件一开始就显示出来的提示信息

search组件的相关文件为:

鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之Search组件

存在问题:在之后的视图界面可能会出现视觉问题,图片的角标太大以至于挡住了图片

解决方法:
1.减小图片的数字,将数字由12变成7

2.增大图片的大小,将图片由20变成24
 

4.统计卡片的开发:

与先前同理,统计卡片的开发也不会直接放入到Index中,我们也会将其变成一个可以到处的组件,在Index中直接调用即可,卡片也是一个由上而下的列式布局所以只需要一个column容器即可,统计卡片由两部分组成,上面一部分为日期选择器,下面一部分为统计信息,并且存在圆角和背景色

4.1日期选择器开发

4.1.1日期选择器开发

日期信息不仅仅是信息,还带有一个倒三角按钮,点击按钮会弹出日期选择器按钮

分析图片发现日期选择器和统计信息使用列式布局+行布局即可,在Column中套用Row并添加基本的文字,对于文字之后的倒三角日期选择按钮则可以再定义一个组件进行单独的设计,设计完成之后直接调用即可

此时我们新建DatePickDialog.ets文件,用来设计单击倒三角按钮后弹出的日期选择对话框

因为声明的是一个自定义的对话框而不是组件,所以使用了@customDialog来设计,而controller: CustomDialogController 表示该对话框组件拥有一个类型为

CustomDialogController 的属性,这个属性通常用于控制对话框的行为,比如显示、隐藏对话框,以及处理用户交互等。

在build()插入DatePicker组件,该组件用于日期的选择

打开其API,其内包含三个参数:

1.Start参数与End参数:代表着日期选择的开始与结束,日期选择器需要框定一个范围,所以才有了Start和End两个参数,在本案例中end的日期应该最晚到当天,不可能自己的饮食记录把明天的饭都吃了,即end值一定是“今天”

2.Select参数:选中的日期

同时也包含了一个属性Luner

作用是用来切换农历与公历,可以自行添加使用

也包含了一个处理时间OnChange

用户选择一个日期就会触发OnChange事件来改变当前的日期,把用户选中的日期传递给我们

其中的DatePickerResult又有三个代表年月日的属性(year、mouth、day)注意:月的范围是0-11;类似一个数组,比现实要小一个月

将其内部的API方法复制粘贴到源代码中

因为没有定义selectedDate对象初值,所以会有报错,我们在上方定义好它的初始值即可(注意是Date类型!)

接下来我们可以开发按钮了,根据布局样例可知,按钮都是在一行中,所以我们使用ROW来新建出一行来,在将按钮放入改行中,更改信息为“取消”和“确定”,用来区分这两个按钮的属性,我们可以设置不同的颜色首先定义好取消方法

.onClick(()=>this.controller.close())//点击调用窗口关闭方法

单击该按钮调用关闭窗口方法,同时,我发现在整个APP中,不止一个地方需要用到日期选择的结果,所以我们在确定按钮中使用一个新的方法来接受住当前日期的值(AppStore:应用的内部存储)调用内部的函数SetOrCreat函数做一个创建或者保存(键值形式)键值不存在则创建、存在则进行覆盖

在切换后的StatsCard的卡片中,我们要@StorageProp('selectedDate')装饰器来读取这个键值

  • 从存储中读取selectedDate的值,如果没有找到,则使用当前日期的开始时间。
  • 创建一个CustomDialogController实例,用于管理DatePickDialog对话框。
  • 当StatsCard组件需要显示日期选择对话框时,可以通过controller来打开和控制这个对话框。

为了数据的持久化,下次再打开的时候日期仍要展示出来(回显)所以要转换成日期类型(this.selectedDate)

同理,下方的Text('2024/06/15')实参‘2024/06/15’也要转换成上述获取到的值

为本行添加点击事件,用户点击倒三角时弹出相应的对话框

.onClick(()=>this.controller.open())

切换日期,日期选择器会显示所切换日期的原理:

选中的日期存储到AppStore中(全局存储,别的文件也会改变)在statsCard文件中通过@storageProp就可以读取到刚刚所存的值,读取到之后,日期选择器就能展示出来,在最终的显示页面因为读取到的selectedDate在build中进行了回显,所以最终页面可以显示出来你所选的日期。所以下次再打开对话框的时候日期就被记录住了而不是被初始化。

鸿蒙(HarmonyOS)系统中的Swiper组件是一个容器组件,主要用于实现滑动切换的效果,类似于轮播图。

Swiper组件在鸿蒙系统中的作用主要是提供一种流畅且具有良好用户体验的滑动切换功能,常用于展示图片轮播、新闻头条、广告等场景。

swiper内部你只需要给他添加子组件即可,他可以自己实现滑动

Swiper(controller?: SwiperController)

鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之Swiper容器组件

鸿蒙Harmony应用开发—ArkTS声明式开发(容器组件:Swiper)

swiper的属性有Index(默认显示第几张图片或者第几个子组件)、autoplay(是否需要子组件自动进行播放(默认false不轮播))、interval(自动轮播周期)、indicator(是否展示导航指示器(默认展示))、loop(是否循环轮播)......

练习,在swiper组件中输入Hello和World,在对应区域出现滑块,运用此方法我们对其内部进行改造,因为效果图中背景颜色是白色,我们需要把上述的Text中的backgroundColor中的颜色删除,在对内容进行输入,我们会发现,输入完数据之后,文字都被挤到了一起,这个时候我们可以通过FlexAlign布局对列布局进行改变。

使用上述命令之后就可以完成对该列一行内容的分布式对齐

上图为调整后的界面

Column({space:CommonConstants.SPACE_6}){ Text('还可以吃') // .fontSize() .fontColor($r('app.color.gray')) .fontWeight(CommonConstants.FONT_WEIGHT_600) Text('1384') .fontColor($r('app.color.light_gray')) .fontSize(20) .fontWeight(CommonConstants.FONT_WEIGHT_700) Text('推荐1690') .fontColor($r('app.color.light_gray')) .fontSize(12) .fontWeight(CommonConstants.FONT_WEIGHT_700) } Column({space:CommonConstants.SPACE_6}){ Text('运动消耗') // .fontSize() .fontColor($r('app.color.gray')) .fontWeight(CommonConstants.FONT_WEIGHT_600) Text('231') .fontColor($r('app.color.light_gray')) .fontSize(20) .fontWeight(CommonConstants.FONT_WEIGHT_700) }

上述代码我们会发现代码的冗余度还是较高,所以我们可以再次用到Builder,使用完Builder之后代码的复杂度变低,而且看起来美观

通过在StatsBuilder()中接受参数,可以完成内容的自定义

@Builder StatsBuilder(label:string,value:number,tips?:string){//第三部分不一定有,所以要加一个判断,可能会不存在这部分 Column({space:CommonConstants.SPACE_6}){ Text(label)//第一部分转成变量名的形式 // .fontSize() .fontColor($r('app.color.gray')) .fontWeight(CommonConstants.FONT_WEIGHT_600) Text(value.toFixed(0))//第二部分的value转成相应的字符串类型 // .fontColor($r('app.color.light_gray')) .fontSize(20) .fontWeight(CommonConstants.FONT_WEIGHT_700) if (tips){//最后一部分进行判断,有则输出,没有不处理 Text(tips) .fontColor($r('app.color.light_gray')) .fontSize(12) .fontWeight(CommonConstants.FONT_WEIGHT_700) } } }

完成对StatsBuilder中的定义之后就可以开发圆环了,将统计信息和文本放入圆环中,并自定义圆环的大小和粗细、颜色等

当然,在自定义环形进度条之前,也要完成对任务进度的展示,使用Progress来实现

这种组件通常以进度条的形式出现,能够展示任务完成的百分比,为用户提供有用的反馈,帮助用户了解任务的状态和进度,也可以用来显示任务的百分比。

Progress 控件可以在水平或垂直方向上显示进度条,并且支持自定义颜色和样式。

        展示完成之后,我们可以对进度条的属性进行开发,其中包括环形进度条的大小、样式和颜色的开发

效果图如左面所示

本部分完成,进行第二部分营养素的开发。

4.1.2营养素统计开发

1.完成营养素ets文件的新建

新建左图所示的营养素ets文件,并且先将其中的内容与CalorieStats设置的相同,在StatsCard.ets文件对应的位置进行导入

在StatsCard的对应的位置导入营养素的文件

但是两张卡片仍存在区别,营养素文件还需要脂肪、碳水等变量,所以要再进行定义

carbon:number = 0 protein:number = 0 fat:number = 0 recommend :number = CommonConstants.RECOMMEND_CALORIE recommendCarbon:number = CommonConstants.RECOMMEND_CARBON recommendProtein:number = CommonConstants.RECOMMEND_PROTEIN recommendFat:number = CommonConstants.RECOMMEND_FAT

需要完成如左图所示的开发,我们发现它的布局一共可以分为两行,第一行为三个环形进度条并配有文字。下一行存在文字的说明。

第一行的设计:环形进度条及其中的内容:

首先,声明Builder构造器,参数分别为label内容、传入的number类型的值和颜色,因为每个环的颜色都是不一样的所以不需要写死,先传入构造器当使用的时候在把实参赋给color完成不同颜色的进度条的设计

@Builder StatsBuilder(label:string,value:number,recommend:number,color:ResourceStr)

其次,完成环形进度条的开发

Progress({ value:value, total:recommend, type:ProgressType.Ring }) .width(95)//调整大小,小于最中间的环即可 .style({strokeWidth:CommonConstants.DEFAULT_6}) .color(color)

最后,完成其中内容的设计与自定义及其每个环形下方的说明信息

Text(`${value.toFixed(0)}/${recommend.toFixed(0)}`)//已经摄入的数量和推荐的数量都要传入 // .fontColor($r('app.color.light_gray')) .fontSize(20) .fontWeight(CommonConstants.FONT_WEIGHT_700)

注意:上述所有的内容都需要放到Stack()重叠器使用

Text(`${label}克`)//label说明你传的是碳水化合物还是脂肪还是其他,根据传入的参数来写 .fontSize(12) .fontColor($r('app.color.light_gray'))

完成所有后的说明信息(例如:碳水化合物多少客?脂肪多少克.....)

4.2饮食统计、饮食信息开发

        由图例可以分析出饮食统计和信息是一个列表,所以我们可以使用一个List进行实现,用Foreach循环来渲染整个组件

        在开始前我们仍需要封装出一个新组件,然后在主界面对应的位置直接调用即可。还是在recowd中新建一个名为recordList.ets的文件。分析图片我们发现图片对每一组进行了分类,每一组的样式都是差不多的。所以在编写页面UI的时候没有必要对每一组的UI单独进行编写,只需要写一组样式,for循环遍历展示一组组不同的样式就可以形成很多组的样式了。

        图片分析可以使用column进行开发 ,分析图片的布局,发现是平铺的所以列的宽度为‘100%’,同时设置背景色为白色,圆角与上述两张卡片的圆角相同,并且我们发下列表内元素并不是紧紧贴边所以我们可以设一个padding来扩大元素间的边距。column定义完成,接下来我们设置卡片

Column(){ } .width('100%') .backgroundColor(Color.White) .borderRadius(CommonConstants.DEFAULT_18) .padding(CommonConstants.SPACE_12)

1.设置每一组的分组信息,首先设置分组的标题,然后设置组内列表。我们没有数据,可以先进行列表的模拟

完成后导出到RecordIndex中,在对应的位置导入.etc文件,并且将权重设为1

在编程和用户界面设计中,

.layoutWeight 是一个属性,通常与布局容器中的子元素相关联。它用于指定子元素在剩余空间中所占的相对权重。当一个布局容器中的总

layoutWeight 值被分配给所有具有权重的子元素时,这些子元素将根据它们的权重比例来填充额外的空间。

再通过调节宽度和第一行与上述卡片的举例来使界面规整

下方图片为调整后的统计信息界面

循环一行的内容为:

Row({space:CommonConstants.SPACE_6}){ //其中的内容为图片+双行文字+千卡 Image($r('app.media.toast')) .width(50) //因为图片后的文字为上下布局,所以还要单独嵌套一个Column列布局 Column({space:CommonConstants.SPACE_4}){ Text('全买土司') .fontWeight(CommonConstants.FONT_WEIGHT_500) Text('one pices') .grayText() } Blank() Text('91千卡') .grayText() } .width('100%') .padding(CommonConstants.SPACE_6)

一行的图片的显示为:

        将一行的内容进行剪切,套用在List循环中可以检查是否可以成功下滑,并且可以将多个食物分为一次早餐的量,如下图所示,为我们后期删除记录打下基础

        删除记录:删除记录的前提是有删除按钮来与用户进行交互,可以给ListItem添加侧滑行为,并且侧滑后出现删除按钮,我们先来设计侧滑之后的图标

,可以使用Builder先来设计图标

@Builder deleteButton(){ Image($r('app.media.ic_public_delete_filled')) .fillColor(Color.Red) .width(20) .margin(5)//删除按钮与其他图片产生一个间距 }

        定义完成之后我们在上面的ListItem中就可以进行使用了删除按钮了,为ListItem添加动作.swipeAction({end:this.deleteButton.bind(this)}),检测是否滑动到最后,滑动到最后则出现删除。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/941248
推荐阅读
相关标签
  

闽ICP备14008679号