-
灵感来源:
1.运动习惯
当代青年普遍面临久坐和缺乏运动的问题,因此App可以鼓励用户定期站起来活动,提供办公室健身操、快速间歇训练等简单易行的运动方案。
2.健康意识
许多青年开始关注健康,但缺乏专业知识。App可以提供健康教育内容,如营养知识、运动科学等,帮助他们建立正确的健康观念。
3.心理健康
现代生活节奏快,压力大,青年群体中心理健康问题日益突出。App可以提供压力管理工具,如冥想指导、情绪日记等,帮助用户缓解压力。
4.社交互动
青年群体社交需求旺盛,App可以设置社区功能,让用户分享运动成果、健康食谱,参与线上挑战,增加运动的社交性和趣味性。
5.个性化定制
根据用户的身体状况、运动偏好和生活作息,提供个性化的运动和饮食建议,帮助用户制定适合自己的健康计划。
6.健康挑战
定期推出健康挑战活动,如“21天运动挑战”、“健康饮食月”等,激励用户积极参与,形成良好的运动和生活习惯。
7.生活平衡
除了运动和健康,App还可以关注用户的工作和生活平衡,提供时间管理工具、工作与休息的建议等,帮助用户实现全面的健康生活。
-
应用介绍:
运动健康APP通常为用户提供一系列功能,帮助他们更好地进行运动锻炼和健康管理。
以下是一些主要功能和应用的介绍:
运动记录:
记录用户的运动数据,如跑步、步行、骑行等,包括运动时间、距离、速度、消耗的卡路里等。训练课程:
提供各种训练课程,如减脂、塑型、增肌等,有些APP还提供瑜伽、舞蹈、搏击等多样化课程。健康监测:
监测心率、睡眠质量、血压、血糖、体重等健康指标,帮助用户全面了解自己的健康状况。饮食管理:
用户可以记录和分析自己的饮食习惯,一些APP还提供膳食建议和营养分析。社区交流:
加入社区或圈子,与其他用户交流健身经验,分享进展,获得动力和支持。个性化计划:
用户可以根据自己的需求定制个性化的训练和饮食计划。健康资讯:
提供健康、运动相关的资讯和科普内容,帮助用户获取科学的运动和健康知识。设备同步:
与智能穿戴设备如手环、体脂秤等同步数据,实现更准确的健康监测和管理。活动参与:
参与线上活动,如跑步挑战、健康打卡等,增加运动的乐趣并激励用户坚持。专业指导:
一些APP提供专业教练的指导和建议,帮助用户更科学、更安全地进行锻炼。
使用运动健康APP的好处在于它们可以为用户提供一个全面的健康管理平台,无论是初学者还是有经验的健身爱好者,都能找到适合自己的训练方法和健康建议。通过这些工具,用户可以更有效地追踪自己的运动进度,获得健康生活的指导,并与志同道合的社区成员交流心得。
主要参考文献:
-
代码结构解读:
-
关键技术
ArkTs
鸿蒙开发应用Deveco stdio
响应式布局
用户首选项
API的使用
组件的抽离与调用
装饰器的使用
自定义弹窗的事先
层叠器的使用
进度条的使用
List列表的使用
TabBar和TabContent页面布局的使用
Badge组件的使用
swiper滚动组件的开发
Progress进度条的设计
Panel弹窗组件的开发
-
实验过程:
1.欢迎页面的设计
1.1欢迎页面的整体原型设计
欢迎页面是一个从上到下的列式布局所以我们使用一个column即可实现,通过观察我们发现欢迎页面的背景色整体是个绿色且背景颜色是铺满整个屏幕的,所以我们可以对column的属性添加一个绿色,宽高比为100%
1.2页面内部元素设计
该页面中心是一张图片,下方的logo也是由图片组成,并且logo下有三行文本。
在开发工具中,我们将已经实现的两个工具先添加到HeimaHealthy中,在AppScope目录下有media文件和element文件,media文件下存放的是应用的图标,element文件夹下存放的则是APP的名称(如下图所示)
下图为已经实现的两个文件
因为我们要开发一个欢迎页面,欢迎页面不在首页中,所以我们要重新创建一welcome文件,用来表示欢迎页。
对于我们的内容,我们可以在一列中分出三行,第一行防止slogn图片,第二行防止logo,最后一行我们放置文字内容
需要注意的是:文字部分的第一行中,‘IPV6’这四个字是带有边框的,我们要使用一个ROW容器来区分‘黑马健康支持’、‘IPV6’、‘网络’。但是我们还需要给‘IPV6’所在的文本添加边框。并且给这些文本添加样式。
在添加样式的过程中我们发现文本的样式都一样,我们可以使用@Entend来将同样的样式抽取回去,然后只需要调用该方法就可以实现一样的样式,减少了代码的冗余度。
Extend(Text)表明方法中的样式只继承与text,只能使用Text的相关的属性。但是样式最终的值可能会不同,我们一开始不能写死,所以最好是写成变量参数的形式,用到的时候直接调用并且传入实参即可。
@Extend(Text) function toumingWhiteFont(opacity: number, fontSize: number = 10) { .fontSize(fontSize) .opacity(opacity) .fontColor(Color.White) }
其二,我们现在可以对‘IPV6’的边框进行单独的编辑。如下代码为为‘IPV6’添加一个实线宽度为1的边框,颜色为白色,平滑圆角的值设置为了15
border({ style: BorderStyle.Solid, width: 1, color: Color.White, radius: 15 }) .padding({ left: 5, right: 5 })
我们可以对slogn的layout的权重设置为1,这样剩余的部分就自动被挤到了下面。
1.3欢迎页面业务逻辑
欢迎页面的业务逻辑如下图所示:进入欢迎页面的时候会进行弹窗,当用户选择同意的时候则跳转到首页,否则推出到桌面。
实现上述的逻辑设计共需要应用两个知识点:用户首选项和自定义弹窗
1.3.1用户首选项
1.3.2自定义弹窗设计
需要使用到的装饰器为@customDialog,声明一个controller的成员变量,它的类型一定要是CustomController(自定义弹窗控制器),它可以用来控制弹窗的状态
我们需要在使用的时候对弹窗进行初始化
我们将弹窗放在一个组件文件中进行编写,我们用到的所有的组件都可以放到view中,然后再view文件夹下我们可以分页面再新建文件夹,根据对应的页面将组件进行归类。
在UserPrivacyDialog文件中我们先声明出来controller弹窗,不需要进行初始化,弹窗的内容我们使用一个colomn布局即可,并且使用padding来保证内容与边框的举例,防止内容太挤影响美观。
我们先为弹窗的设置一个标题,并且将事先定义好的字符串说明传入标题中,但是在没有Entry的程序中我们无法进行预览,解决方法是在头部添加一个@proview,这样计算机可以对弹窗进行临时的预览。
预览界面如下
我们再导入第二串字符串(内容),正文和标题的样式不能完全一样,所以我们使用字体的相关属性对标题和内容进行编辑。
完成样式定义的标题和内容的图片如下:
我们最后声明两个按钮,并为按钮添加相应的点击事件处理逻辑和样式。
1.事件处理逻辑:
因为我们的业务逻辑是点击‘同意’的时候进入首页,点击‘不同意’的时候退回到桌面,可以定义两个函数,触发点击事件的时候调用对应的点击事件即可。
confirm:()=>void cancel:()=>void
同意按钮:调用对应的确认函数并且使这个窗口关闭
Button($r('app.string.agree_label')) .width(150) .backgroundColor($r('app.color.primary_color')) .onClick(()=>{ this.confirm() this.controller.close() })
不同意按钮:
Button($r('app.string.refuse_label')) .width(150) .backgroundColor($r('app.color.protein_color')) .onClick(()=>{ this.cancel() this.controller.close() })
定义完这两个功能之后,我们对函数进行导出,在Welcome中我们同样需要定义一个CustomDialogController类型的变量controller,并对其实例化。
controller: CustomDialogController = new CustomDialogController
在声明的过程中,我们需要传入一个builder属性的对象,builder属性的值就是你刚刚定义的UserPrivacyDialog。但是这个组件在使用过程中需要传递一个参数,但我们并没有定义,所以,我们需要定义两个处理函数,关于点击后跳转到某个页面并保存到用户首选项的和点击后退出App的处理函数。
onConfirm() { //1.保存首选项 console.log('testTag', 'onConfirm') //出现问题后添加的断电,判断该方法是否执行了 PreferenceUtil.putPreferenceValue(pref_key, true) //2.跳转到首页 this.jumpToIndex() } exitAPP() { //退出APP this.context.terminateSelf() }
上述两个方法声明完成之后我们就可以进行调用了,至此,弹窗的功能定义完成,问题是我们现在并不知道该弹窗具体什么时间出现,应该声明一个方法,该方法就是用于弹出该弹窗。当我们点击同意或者取消的时候再关闭上述声明的方法。
声明的方法如下:
退出APP的实现原理需要用到context,它代表了一个应用程序的上下文环境。在 Android 和其他操作系统中,context 通常用于提供应用程序与系统之间的交互接口,允许应用程序访问系统服务、启动活动(Activity)、服务(Service)等。获取到上下文的方法是使用getcontext方法。获取到的上下文的类型是common下的UIabilityContext类型。我们拿到context之后再调用this.context的terminateSelf方法就可以终结程序的运行。
首选项操作aboutAppear出现的时候我们要进行一个判断,判断是否同意首选项的出现,同意与不同意又有两种处理方式:
1.同意则进行首页的跳转,不同意则出现弹窗。我们根据已经提供的util文件夹下的Preference首选项中定义好的首选项操作。我们需要在加载用户首选项的时候的context的参数传入。
完成之后我们就可以在Welcome中进行读取,使用的方法是getPreferenceValue进行读取,读取的时候不要忘记传入一个key值(常量)。我们可以提前声明key的值。使用const说明该key值是一个只读类型,定义了之后就不能改变了。getPreferenceValue()中传入一个key和一个默认的结果,我们默认先传入false,假设默认并没有加载到页面。没加载到就不同意,不同意就会出现弹窗。因为整个读取过程是异步的,所以要使用await来修饰,同时在声明该方法的时候也要使用async。
接下来我们就可以进行判断了,如果同意我们就跳转到首页,如果不同意我们就出现弹窗。我们先定义可以成功跳转到首页的方法JumpToIndex,在其中使用replace方法而不是用push方法,因为push方法会把当前页面压入栈中,结合我们的欢迎页面仅在应用启动的时候加载一次,所以没有必要进行压栈,直接replace替换到即可。
为了方便加载数据,我们可以设置一个setTimeout的延时任务,第一个参数设置router跳转,第二个参数我们设置一个延迟跳转的时间,假设为1000ms。最后我们定义Onfirm确认功能,用户点击同意的时候我们仍需要调用PreferenceUtil方法,将用户首选项存入的方法不是get而是putPreferenceValue,存的内容还是事先定义好的Key键,这个时候的值就可以设置为ture了,同意了就可以存入true了。最后保存成功之后仍需要跳转,所以还需要调用一次JumpIndex方法。
这时出现问题我们在模拟器打开运行的时候没有进入Welcome欢迎界面而是直接进入了Index界面,原来是我们的EntryAbility中的舞台初始化出现了问题。我们期望的默认加载页面时Welcome不是Index。所以我们将EntryAbility的默认加载更改即可。