登堂—HarmonyOS Practice《鸿蒙应用开发实战-张荣超》|自学笔记

开发 OpenHarmony
Lite wearable和wearable所适用的API不一样!开始之前请在config.json-deviceTypel里确定自己所在的项目是Lite wearable。

[[411062]]

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com

一、书中致谢&前言

2021年6月29日23:10:32

  1. 51CTO鸿蒙技术社区很有用
  2. 本书使用DevEoc中的平台为Lite Wearable,即轻量级的可穿戴产品的开发
  3. 本书介绍的是一个呼吸训练系统APP的开发全过程,
  4. 采用 项目导向的方式 和 任务导向的方式 ,共计36个任务每个任务分为3个部分,包括运行效果、实现思路、代码详解。
  5. 本书三章,第一章为“鸿蒙操作系统简介”;第二章为“项目准备工作”;第三章为“呼吸训练实战项目”
  6. 代码下载网址

这代码使用的DevEco版本太老了!!!

二、学习完本书后自己总结的提示和建议

  1. Lite wearable和wearable所适用的API不一样!开始之前请在config.json-deviceTypel里确定自己所在的项目是Lite wearable。
  2. 同理!canvas画布组件同样在Lite wearable不支持!使用chart就行
  3. 同理!关于滑动事件。direction的值比之老版本有改变,各位读者请注意,up和down不可用,应用top和bottom来表示上下。
  4. 在预期效果达不到的时候,多用console.log(“XXXX”);打印信息,来查看函数是否如期调用。
  5. 动态数据绑定在本APP中使用极多,不管是出于显示和数据的分离作用,还是通过动态数据简化代码。都极其好用。在JS-dada中规定字典(值、数组)的格式请注意。
  6. 主页面是布局和图片旋转、倒计时页面是页面跳转、压力占比页面是进度器应用、心率页面是线形图的应用、活动页面是柱状图的应用、压力分布页面是2d绘制引擎的应用(但canvas不能用在Lite wearable,用的还是chart)、最大摄氧量页面是弧形进度的应用、学习交流页面就是贴图。
  7. 用params指定要传递的数据。
  8. 容器与组件的应用还需要更多的案例去熟悉,最终期望到达熟稔于心的地步。包含组件与组件、组价与容器。
  9. 随机数组,随机数的生成,应成为定式记住。
  10. 图片的选择image、src。
  11. 书中和资料上的代码都没有格式化,我觉得这样不好,ctrl+alt+L就代码格式化了,方便查看、方便阅读、方便修改。
  12. 页面与页面的跳转(router-uri)-URI最准确的是在config.json-Page里面看,书中的跟实际的不太一样
  13. 通过style属性中的animation-duration样式指定logo图片转动一次的时间,通过style属性中的animation-ireration-count样式指定logo图片转动
  14. 参数、形参、实参、this、自定义函数、函数调用、函数定义、逗号、冒号、循环语句、选择语句、求最大、求最小、属性值

三、第一章 鸿蒙操作系统简介

  • 时间:2021年6月29日23:28:46
  • 1.1 1+8+N全场景
  • 其实也就是,构建一个基于鸿蒙生态下的IoT
  • 1.2 分布式(理解:多个人干多个活儿)
  • 分布式软总线与传统意义上的硬总线的区别,分布式软总线承担了任务总线、数据总线、总线中枢。任务总线:负责将应用程序在多个终端上快速分发;数据总线:负责数据在设备间的高性能分发和同步;总线中枢:负责将应用程序控制,用于自动发现并组网,以及维护设备间的拓扑关系。
  • 鸿蒙操作系统的分布式软总线可以实现异构融合网络
  • 分布式数据管理也是鸿蒙操作系统的核心技术

四、第二章 项目准备工作

  • 时间:2021年7月3日23:16:46

2.1 搭建开发环境(已通过之前的学习已经成功搭建)

  • 2.11安装Node.js
  • 2.1.2安装DevEco Studio

2.2Hello World

  • 注意一个previewer就行
  • 每个页面都包含一个hml文件(结构)、一个css文件(样式)、一个js文件(行为)
  • 具体的来讲就是,hml文件是页面的结构,用于描述页面中包含哪些组件;css文件是页面的样式,用于描述页面中的组件都长什么样子;js文件是页面的行为,用于描述页面中的组件是如何进行交互的
  • index.js 中定义了一个变量title,它的值是‘World’,是个占位符,在程序的运行过程中动态确定的,这种技术称之为动态数据绑定

五、第三章 呼吸训练实战项目

  • 时间:2021年7月5日15:50:28
  • 综述:对于整个APP的一个介绍

3.1任务1:在主页面中添加一个按钮并响应其单击事件

  • 时间:2006年7月6日14:17:12
  • 调试了一下午发现由于书籍用的DevEco版本太低了,导致有很多不一样,以至于运行不了。
  • 要实现的效果:构建点我的页面
  • 时间:2021年7月7日14:12:47
  • 经过更新DevEco Studio 2.2.0.200 x64
  1. border-bottom-width 
  2. width 

上述两者不一样,经过调试已经可以得出界面

时间:2021年7月7日20:46:39

对位置进行调整

单击该按钮后打印一条log

在编程过程中,

  1. //index.js 
  2. //定义clickAction函数 
  3. onInit() { 
  4.         this.title = this.$t('strings.world'); 
  5.     }, 
  6.     clickAction(){ 
  7.          console.log("我被单击了"); 

要用,隔开,分号的英文还是中文很重要

  1. //index.hml 
  2. //按钮的onclick单击事件 
  3. <input type="button"  value="点我" class="btn" onclick="clickAction"  /> 

编译器右上角有个小虫子,是Debug按钮(Shift+9),要想看到打印就需要Debug

非模式的浮动窗口

因为教材使用的是Litewearable而现在2.2版本的DevEco都是Wearable了。所以不能用previewer了,就只能用远程虚拟机Device Manager

成功运行

3.2任务2:添加训练页面并实现其与主页面之间的相互跳转

时间:2021年7月7日21:17:59

分析:行为相似,稍作改变,可以调用router.replace()语句实现页面间的跳转,在调用该语句的时候通过Uri指定目标页面的地址

创建JS页面

进行跳转

时间:2021年7月7日22:30:45

经过不断试错,加上console.log的提示发现,训练页面可以跳转主页面,但主页面无法跳转训练页面。

经过半个多小时的调试(误入歧途,妄想通过更改config.json中的deviceType来实现wearable到litewearable的转化),之前一直想的是因为previewer自身的问题,认为无法跳转是因为项目本身是wearable的,而不是Litewearable的导致了认知偏差,完全没有想到是uri出了问题。

最后完成的效果如下GIF

3.3任务3:验证应用和每个页面的生命周期事件

该任务的目的就是通过打印生命周期各个阶段的名称,来感受每个页面的生命周期

时间:2021年7月7日22:43:05

生命周期(onInit-onReady-onShow-onDestroy)

  1. onInit() { 
  2.     console.log("主页面的onInit()正在被调用"); 
  3.  
  4.     router.replace({ 
  5.         uri:'pages/index/index' 
  6.     }); 
  7. }, 
  8. onReady() { 
  9.     console.log("主页面的onReady()正在被调用"); 
  10. }, 
  11. onShow() { 
  12.     console.log("主页面的onShow()正在被调用"); 
  13. }, 
  14. onDestroy() { 
  15.     console.log("主页面的onDestroy()正在被调用"

其具体实现

3.4 任务4:在主页面中显示logo和两个选择器

时间:2021年7月7日23:09:03

思路:使用Image组件显示鸿蒙呼吸训练的logo。使用picker-view组件显示logo左右两边的选择器。

关于copy图片的hm.png的问题卡了一阵子

之后是关于图片与按钮的自适应问题调试了一阵子

时间:2021年7月7日23:47:20

时间:2021年7月8日14:18:57

卡了太久太久了。从上午到下午,不过有经验了,以后有问题从开发文档进行查询答案。

下午下课问了四个实训老师,还是存在问题

时间:2021年7月8日23:29:21

在51CTO学院张荣超老师的企业微信群里问了问题,希望可以得到解答

时间:2021年7月8日23:44:47

张荣超老师回复!发了源码,我进行研究研究。

终于解决了!!!!

时间:2021年7月9日00:59:21

存在两个问题:

1.app.js中引号的问题

Litewearable的JS API与wearable的API不兼容。,所以我把config.json改了

最后修改后的页面

3.5 任务5:在指定选择器的默认选中项并获取选中项的值

时间:2021年7月9日09:09:54

range的类型:Array

使用时需要使用数据绑定的方式,如range = {{data}},js中声明相应变量:data:[“15”, “20”, “25”]。

selected的相关说明:

selected:设置文本选择器的默认选择值,该值需要为range的索引。

设置时间选择器的默认取值,格式为 HH:mm;

change的说明:

在使用的时候要用onchange

文本选择器选定值后触发该事件。参数:{ newValue: newValue, newSelected: newSelected }

时间选择器选定值后触发该事件。参数:{ hour: hour, minute: minute}

  1. changeAction1(pv) { 
  2.     console.log("左边的选中项:" + pv.newValue); 
  3. }, 
  4. changeAction2(pv) { 
  5.     console.log("右边的选中项:" + pv.newValue); 
  6. }, 

3.6 任务6:将主页中选择器的值传递到训练页面

时间:2021年7月9日14:35:07

页面跳转的时候:用uri指定目标页面,用params指定要传递的数据。

在生命周期事件函数onInit()中获取主页面传递过来党的值,并将其打印到log中,因为选择器的值存放在了一个字典中,并且对应的key分别是data1和data2,所以训练页面中可以通过this.data1获取传递过来的左边选择器的值,右边同理。

  1. console.log("接收到的左边选择器的值:" + this.data1); 
  2. console.log("接收到的右边选择器的值:" + this.data2); 

3.7 任务7:修改主页面和训练页面中按钮的文本及样式

时间:2021年7月9日14:52:17

对font-size样式修改按钮的文本大小

通过background-color样式修改按钮的背景颜色

通过border-color样式修改按钮的边框颜色

按钮颜色还挺好看的

training页面的按钮同理

3.8 任务8:在训练页面显示总共需要坚持的秒数

时间:2021年7月9日15:03:43

因为training页面需要显示主页面选择器选择的值作为参数,所以这里需要采用动态绑定的方式。

  1. picker1value = this.key1; 
  2. picker2value = this.key2; 
  3.  
  4. if (picker1value == "1") { 
  5.     picker1seconds = 60; 
  6. else if (picker1value == "2") { 
  7.     picker1seconds = 120; 
  8. else if (picker1value == "3") { 
  9.     picker1seconds = 180; 
  10.  
  11. if (picker2value == "较慢") { 
  12.     picker2seconds = 6; 
  13. else if (picker2value == "舒缓") { 
  14.     picker2seconds = 4; 
  15. else if (picker2value == "较快") { 
  16.     picker2seconds = 2; 
  17.  
  18. this.seconds = picker1seconds; 

这里比较笨拙可以用

  1. picker1seconds=picker1value*60; 

3.9 任务9:在训练页面倒计时显示再坚持的秒数

时间:2021年7月9日15:23:13

在训练页面的生命周期事件函数onShow()中调用==setInterval()==函数创建一个定时器,并在调用时指定定时器要执行的动作及其时间间隔

  1. run1() {    this.seconds--;    if (this.seconds == 0) {        clearInterval(timer1);        timer1 = null;        this.isShow = false;    }}, 

3.10 任务10:再坚持的秒数在倒计时结束时隐藏显示的文本

时间:2021年7月9日15:33:33

将某个组件的show属性的值设置为false从而隐藏该组件

注意:隐藏组件之后,它在页面中所占的空间仍然存在

  1. seconds: 0,//这个,必须要加上isShow:truetimer1 = setInterval(this.run1, 1000); 

3.11 任务11:在训练页面根据呼吸节奏交替显示“吸气”和“呼气”

时间:2021年7月9日15:38:36

在training页面交替显示,就需要在training页面的生命周期函数onShow()中调用==setInterval()==创建一个定时器,并在调用时指定定时器要执行的动作及其时间间隔。

因为我们设定了较慢、舒缓、较快,所以这里有一个节奏的转换,也就是说要用不同的时间间隔区别不同的selected的选择

需要声明一个全局变量counter作为计时器,将其初值设置为0

  1. run2() {    counter++;    if (counter == picker1seconds / picker2seconds) {        clearInterval(timer2);        timer2 = null;        this.breath = "已完成";    } else {        if (this.breath == "吸气") {            this.breath = "呼气";        } else if (this.breath == "呼气") {            this.breath = "吸气";        }    }}, 

3.12 任务12:每次吸气或呼气时都实时显示进度百分比

时间:2021年7月9日16:18:34

还是使用定时器

  1. run3() {    this.percent = (parseInt(this.percent) + 1).toString();    if (parseInt(this.percent) < 10) {        this.percent = "0" + this.percent;    }    if (parseInt(this.percent) == 100) {        this.percent = "0";    }    if (timer2 == null) {        clearInterval(timer3);        timer3 = null;        this.percent = "100";    }}, 

3.13 任务13:每次吸气或呼气时logo都顺时针转动一周

时间:2021年7月9日17:13:22

通过style属性中的animation-duration样式指定logo图片转动一次的时间,通过style属性中的animation-ireration-count样式指定logo图片转动

logo顺时针转动一周的时间,就是一次呼气或吸气的时间picker2secons,但是对于training.hml中的animation-duration样式,要指定其点位“s”,因此要将picker2seconds+“s”赋值给data中的duration。

logo转动的次数就是吸气和呼气的总次数,即picker1seconds/picker2seconds。

时间:2021年7月10日09:14:02

排查了很久为什么图片转不起来

原因居然在这里:

可恶!

终于成功了!

3.14 任务14:添加倒计时页面并实现由主页向其跳转

时间:2021年7月10日09:17:46

就是创建新页面。新布局,新组件

3.15 任务15:在倒计时页面进行训练指引的3秒倒计时

时间:2021年7月10日09:25:24

  1. run() {    counter = counter - 1;    if (counter != 0) {        this.imgsrc = "/common/images/" + counter.toString() + ".png";        this.seconds = counter.toString();    } else {        this.imgsrc = "";        this.seconds = "";        clearInterval(timer);        timer = null;        router.replace({            uri: 'pages/index/training/training',            params: {                "key1": pv1,                "key2": pv2            }        })    }}, 

3.16 任务16:3秒倒计时结束后跳转到训练页面并传递主页面的数据

时间:2021年7月10日09:37:38

单击主页面中的按钮跳转到倒计时页面,读秒结束后,跳转到训练页面并将主页的数据传递给训练页面

倒计时页面中,将主页面传递的值作为value存放在字典中,并且通过params传递给训练页面。在训练页面中通过key,从字典中获取两个选择器的值。

梳理:

  1. //需要的配套格式import router from '@system.router';clickAction() {        router.replace({            uri: '',            params:{"":,"":}        });    },//主页面 params:{"data1":picker1value,"data2":picker2value}//倒计时页面params: {              "key1": pv1,           "key2": pv2                }//训练页面  picker1value = this.key1;        picker2value = this.key2; 

3.17 任务17:呼吸训练结束后右滑查看训练报告

时间:2021年7月10日09:56:58

在多个连续的text组件中使用if-elif-else结果,以便从中选择一个text组件进行显示。在页面的最外层div组件中添加onswipe属性,从而在页面触发滑动事件时自动调用指定的自定义函数

关于if-elif-else的使用说明:因为再坚持这个text在倒计时结束以后会null,但空间并没有释放,所以需要在相同的位置进行多文本的选择,以便让空间得以充分应用

右滑:在训练页面,添加一个自定义函数,定义一个形参,在函数体中通过e.direction的值判断滑动的方向,如果等就跳转

关于onswipe属性:设置值为自定义的toReport1Page函数,这样右滑的时候触发页面的onswipe事件,从而调用自定义的toReport1Page函数。

  1. <div class="container" onswipe="toIndexPage">
  1. toIndexPage(e) {    if (e.direction == 'left') {        router.replace({            uri: 'pages/index/index'        });    }} 

3.18 任务18:将第1个训练报告页面的标题修改为压力占比

时间:2021年7月10日14:09:30

之后使用的数据都是随机生成的测试数据,其目的使其学会如何对数据进行分析和可视化展示

flex-direction样式用于指定容器所在组件的排列方向,可选值有两个:row和colum,分别表示水平方向和竖直方向。选其一为主轴,另外一个为副轴。

justify-content用于指定容器内所有组件在主轴上的对齐方式

align-items用于指定容器内所有组件在副轴上的对齐方式

书本里做了四个容器,关于着三个组件不同值的可视化案例教程,很清晰的把三个方法,十个可选值

3.19 任务19:在压力占比页面的标题下方显示压力分类的列表

时间:2021年7月10日14:35:38

联合使用list和list-item组件来展示一个列表中的多个列表项。

在list组件中使用for属性并通过动态数据绑定的方式指定要迭代的数组。在list-item组件中使用$item并通过动态数据绑定的方式指定迭代过程中的数组元素。

数据和显示需要分离

每一个列表项数据都可以用{{$item}}来表示

  1. <div class="state-percent">    <text class="state">        {{ $item.state }}    </text>    <text class="state">        {{ $item.percent }}%    </text></div> 

3.20 任务20:在压力分类的右边显示对应的压力占比

时间:2021年7月10日15:09:52

在onInit()中,随机生成若干个指定范围内的整数,将其作为所有压力状态的数据。根据随机生成的整数统计每种压力状态所占的百分比,并通过动态数据绑定的方式将其显示再列表中。

Math.floor(x)用于返回小于等于x的最大整数

push()函数将生成的随机数添加到stateData数组中

  1. onInit() {    let stateData = [];    for (let i = 0; i < 20; i++) {        stateData.push(this.getRandomInt(1, 99));    }    this.countStatePercent(stateData);}, 

调用countStatePercent()自定义函数,并将stateData作为实参传递给形参stateData

在自定义函数体中用四个计数器,通过for循环对stateData数组中的所有压力状态数据进行遍历,并在遍历过程中判断每个状态压力数据的范围,使用相应的计数器进行个数的统计

3.21 任务21:在每个列表项的下方显示压力占比的进度条

时间:2021年7月10日15:31:43

通过动态绑定的方式指定style属性的值

在list-item组件中添加一个progerss组件(进度条),percent属性为进度。

  1. <progress class="progress-bar" percent="{{$item.percent}}" style="color: {{$item.color}};"/> 

3.22 任务22:添加第2个训练报告页面并响应滑动事件

时间:2021年7月11日10:36:04

就是创建页面,并通过onswipe属性,触发滑动事件自动调用指定的自定义函数

switch函数+router

  1. //最开始调试的代码!有错!关于direction的    toNextPage(e){        switch(e.direction){            case'left':            router.replace({                uri:'pages/index/index'            });            break;            case'down':            router.replace({                uri:'pages/index/report1/report1'            });        }    }} 

 Tips:直接点previewer可能会达不到效果,需要Debug(小甲虫)

大无语事件!大无语事件!

经过不断的控制变量调试,发现只有左右滑动才可以正常。上下滑动无动于衷,添加了生命周期,观察发现!上下滑动时,生命周期没有调用!!!!!!我就怀疑代码错了,然后仔细比对,发现没有问!没有问题!没有问题!那问题出现在哪儿了呢,排除跳转页面uri地址问题,排除了因为冒号引号的问题,排除了函数名变量名参数名不对应的问题,排除了其他页面有干扰的问题,然后我就怀疑标签direction的使用方法是不是错了。经过查验发现网上都是JS的direction标签、微信小程序的direction标签,CSS中direction的属性。对照Breathing源码发现,是因为新版的DevEco中上下左右的属性值变化了。新版的上下左右

上-top(老版本-up)

下-bottom(老版本-down)

左-left

右-right

最后说一句!!!好气好气好气!

时间:2021年7月11日12:24:15

  1. //调整以后的代码toNextPage(e) {    switch (e.direction) {        case 'left':        router.replace({            uri: 'pages/index/index'        });        break;        case 'bottom':        router.replace({            uri: 'pages/index/report1/report1'        });    } 

 才学到的用ScreenToGif做GIF巨方便!

3.23 任务23:在第2个训练报告页面中显示除心率曲线之外的所有内容

时间:2021年7月11日20:17:45

设置有文本组件,心率通过动态数据绑定的方式将其显示在页面中,每个列表项都由一张图片和一个文本组成

  1. //设置的两个图片,用动态绑定加数组简单的抒写其地址<image class="icon" src="/common/images/{{ $item.iconName }}.png"/><text class="maxmin"

 在data中将maxmin占位符初始化为一个字典数组,该数组包含两个字典,分表表示心率最大值和心率最小值的相关信息

  1. data: {    maxmin: [{                 iconName: 'max',                 mValue: 0             },             {                 iconName: 'min',                 mValue: 0             }],    average: 0}, 

 把压力页面的getRandomInt的函数复制过来,该函数用于随机生成一个介于min和max之间的整数,经过for循环执行的100次迭代,在每一次迭代中自定义函数随机生成的数经过push()的添加,最后达到hearRates数组的随机定义。

  1. getRandomInt(minmax) {    return Math.floor(Math.random() * (max - min + 1)) + min;}, onInit() {        let heartRates = [];        for (let i = 0; i < 100; i++) {            heartRates.push(this.getRandomInt(73, 159));        }        this.countMaxMinAverage(heartRates);        console.log("心率页面的onInit()正在被调用");    },        countMaxMinAverage(heartRates) {        this.maxmin[0].mValue = Math.max.apply(null, heartRates);        this.maxmin[1].mValue = Math.min.apply(null, heartRates);        let sum = 0;        for (let index = 0; index < heartRates.length; index++) {            sum += heartRates[index];        }        this.average = Math.round(sum / heartRates.length);    } 

 耽误一阵子时间,因为生成随机素组的时候,返回参数那里,自定义函数名字用的压力页面的自定义函数导致没有,随机数组没有正常生成

最后成功

3.24 任务24:在心率曲线页面中显示绘制的心率曲线

时间:2021年7月11日21:36:20

使用chart组件绘制心率曲线图,通过动态数据绑定的方式

制作图表需要在x、y轴上面设置参数。data中将options占位符的值初始化为一个字典,字典包含两个元素,分别用于设置x轴和y轴的参数。data中将datasets初始化为一个字典,gradient用于表示折线向下填充颜色到x轴,第二个元素是data,用于指定心率图中的数据。

特别的!对于chart线条和填充的颜色我不是很满意,我就查了开发文档,对于chart的属性进行了查询,

  1. options: {            xAxis: {},            yAxis: {                min: 0,                max: 160            }        },        datasets: [{                       strokeColor: '#1883d5',                       fillColor: '#1ed1fc',                       gradient: true,                       data: []                   }] 

 最后完成了心率页面

3.25 任务25:添加第3个训练报告页面并响应事件

时间:2021年7月11日22:15:32

就是左滑右滑的的功能实现

贯穿压力页面、心率页面、活动页面

3.26 任务26:在第3个训练报告页面中显示除活动分布图之外的所有内容

时间:2021年7月11日22:39:20

四个组件包含文本、图片的构造

定义一个名为getRandomZeraOrOne的函数,该函数用于随机生成一个整数0或1,在函数体中,Math.random()用于生成一个介于0和1之间的随机数。Math.floor(x)用于返回小于等于x的最大整数。

定义一个名为countActivityPercent的函数,其形参为activity,该函数用于技术activity中整数0和1所占百分比

3.27 任务27:在今日活动分布页面中显示绘制的今日活动分布图

时间:2021年7月11日23:16:57

与心率页面不一样的是今日活动分布页面的chart组件的type属性选择的是bar,代表是柱状图。通过stuck组件来堆叠其中的组件,从而分别绘制活动柱状图和静止柱状图。

stack:堆叠容器,子组件按照顺序依次入栈,后一个子组件覆盖前一个子组件。

3.28 任务28:添加第4个训练报告页面并响应滑动事件

时间:2021年7月12日09:42:41

添加页面并添加相应滑动,不多赘述

3.29 任务29:在第4个训练报告页面显示除压力分布图之外的所有内容

时间:2021年7月12日09:52:37

压力分布页面跟心率页面构造及其相似。四个大组件,不赘述

出现问题了!在老版本的canvas组件不能再新版本使用

canvas画布:支持手机、平板、智慧屏、智能穿戴

但不支持轻量级智能穿戴!!!Lite wearable不配

完成了!

 

3.30 任务30:在压力分布页面中绘制压力分布图

时间:2021年7月12日10:42:00

书中对于canvas画布组件的应用,不用用了现在,不过大致说一下书中的思路,通弄过canvas组件中的ref属性获得其对应的对象实例,并调用getContext(‘2d’)函数获得2D绘制引擎,在遍历所有压力数据的过程中调用fillRect()函数对压力分布图中的柱子逐一进行绘制

  1. //书中的<canvas class="canvas" ref="canvas"></canvas> 
  1. //现在的<chart class="chart" type="bar" options="{{ options }}" datasets="{{ datasets }}"></chart> 

这里需要说明一下,chart的type属性两种,bar表示的是柱状图,line表示的线形图。

相应的在生命周期onShow中,通过引用this.$refs.canvas获得report4组件的对象实例,然后调用getContext(‘2d‘)函数获得2D绘图引擎。然后通过forEach()函数进行对pressure数组中的随机压力值进行遍历,其中element表示在遍历过程中数组的当前元素。

  1. //书上不能用的onShow(){var context =this.$refs.canvas.getContext('2d');    let leftTopX=0;    presuress.forEach(element =>{        context.fillStyle=this.getColorHexByValue(element);        let leftTopY=180-element *1.8;        let width=7;        let height=element*1.8;       context.fillRect(leftTopX,leftTopY,height,width);        leftTopY +=8;    });} 
  1. //获取柱子的颜色的代码getColorHexByValue(value) {    if (value >= 80 && value <= 99) {        return "#ffa500";    } else if (value >= 60 && value <= 79) {        return "#ffff00";    } else if (value >= 30 && value <= 59) {        return "#00ffff";    } else if (value >= 1 && value <= 29) {        return "#0000ff";    }}, 
  1. //用了chart那么这包含48个数组的pressure,就要定义48个字典定义柱子,for (let i = 0; i < 48; i++) {    let value = pressures[i];    this.datasets[i].fillColor = this.getColorHexByValue(value);    this.datasets[i].data = [value];} 

用不了画布就很麻烦!就需要在data那里就定义48组数据,每组为半个小时。

不过完成了!

3.31 任务31:添加第5个训练报告页面并响应滑动事件

时间:2021年7月12日11:05:18

跟之前的页面报告页面同样的,不赘述

3.32 任务32:在第5个训练报告页面中显示除弧形和星号之外的内容

时间:2021年7月12日11:12:12

最大摄氧量页面,需要显示页面标题、最大摄氧量及其单位、摄氧量等级水平、完全跟前几个页面的构建大同小异

不过其中不一样的地方在于,正中间的两位数字,由两个图片构成,但其中有一个关系需要体现,如果小于十,第一张图if(false)(不能用show,使用show的话就是占位符,还在那个位置,我们希望他不在),唯独使用第二张图片显示最大摄氧量。

  1. //对应图片的hml<div class="number-container">    <image if="{{isShow}}" class="number-icon" src="/common/{{first}}.png"/>    <image class="number-icon" src="/common/{{second}}.png"/></div> 
  1. //对应图片的jsonInit() {    let vo2max = this.getRandomInt(1, 70);    let vo2max_str = vo2max.toString();    if (vo2max_str.length == 2) {        this.first = "num-" + vo2max_str[0];        this.second = "num-" + vo2max_str[1];    } else {        this.second = "num-" + vo2max_str;        this.isShow = false;    }    this.level = this.getLevelByValue(vo2max);}, 

 完成!

3.33 任务33:在最大摄氧量页面显示绘制的弧形

时间:2021年7月12日11:40:13

通过progress组件的type属性设置为“arc”来绘制弧形,通过stack组件来堆叠其中的子组件

progress组件percent属性设置为百分之50,添加style属性用来设置进入条样式。start-angle设置为220(起始角度)。

  1. <progress class="progress" type="arc" percent="50" style="color : #ff0000; start-angle : 220;"

弧度百分之50的效果图

接下来是七彩阳光环节,哈哈哈,就是七个颜色弧形

 3.34 任务34:在最大摄氧量界面的对应弧形和角度上面显示星号

时间:2021年7月12日12:06:26

嗨,还是使用的canvas,其思路就是X-Y轴的绘制,然后添加“*”的文本

不过呢现在就用的是

  1. //现在就比较直接添加组件,然后在js里直接设置对应位置<div class="pointer">    <text class="pointer-txt" style="margin-top: {{y}};margin-left: {{x}};">        *    </text></div> 
  1. //css.pointer{    width: 454px;    height: 454px;    background-color: transparent;}.pointer-txt{    font-size: 38px;    color: yellow;} 
  1. //在js的onInit的里面直接动态绑定x、y的值let angle = -230 + vo2max * (280 / 70);this.x = Math.round(218 + 193 * Math.cos(angle * Math.PI / 180));this.y = Math.round(218 + 193 * Math.sin(angle * Math.PI / 180)); 

完成!

3.35 任务35:添加学习交流联系方式页面并响应滑动事件

时间:2021年7月12日12:15:04

新建一个contact页面,添加相应的文本和router.replace的滑动跳转,不赘述,要完结了!要学完了!冲冲冲!

3.36 任务36:在学习交流联系方式页面中显示二维码并完成项目收尾

时间:2021年7月12日12:22:15

使用image组件显示二维码,就是一个收尾工作喽!冲冲冲!

完结撒花的时候因为图片的比例问题,又在华为开发文档里面去学习了一下image组件哈哈哈。

最后选的是自己以前剑网三丐帮的一张图片!

潜龙勿用!自强不息!

后面收尾有一个简单的提示语的添加(text组件)

书上的完结!

六、对项目的一些调整和感想

(一)点击重新开始的按钮太大了,下面的框框都兜不住了

时间:2021年7月12日12:59:50

对训练页面的btn按钮的进行调整(css)

  1. .btn {    width: 280px;    height: 50px;    font-size: 38px;    background-color: aquamarine;    border-color: aquamarine;    margin-top: 15px;} 

(三)一点感想

时间:2021年7月12日13:08:29

首先我很感谢《鸿蒙应用开发实战》这一本书!当然最应该感谢的是张荣超老师,他写此书是开拓性的行为,虽然现在DevEco的版本迭代很快,书里的部分内容需要调整,但试错与改BUG本来就是一名程序猿需要去干的,原封不动的照抄代码,反而效果可能没有那么美丽!还有就是在学习的过程中我还加入了张荣超老师的粉丝企业微信,然后在里面得到了老师耐心的讲解!!!真的太佩服他了!更甚,张荣超老师在51CTO社区发的学习鸿蒙的文章也很有代表性!最近发的【张荣超老师】鸿蒙卡片开发超细致总结 ,也特别特别的详细!ps:接近凌晨十二点张老师也回复了!!!!

总结一下这本书和这段时间的学习:没有案例没有项目的学习,是支撑不起实际开发的,选择这本书就是为了可以快速的上手,在简单项目中学习DevEco的相关设置、一些快捷键的使用;DevEco中JavaScript的Lite wearable的开发,熟悉轻量级智能手表的API,

在这里就这个项目还有可能完善的地方就是,使用全部的轻量级手表专属API中,

《鸿蒙应用开发实战》使用的组件:

容器组件:div(基础容器)、list(图片文本的列表项容器)、list-item(< list >的子组件,用来展示具体的item)、stack(叠堆容器)、swiper(滑动容器)

基础组价:chart(线性图、柱状图)、image(图片)、image-annimator(图片帧动画播放器)、input(交互组件)、picker-view(嵌入页面的滑动选择器)、progress(进度条,用于显示内容加载或操作处理进度)、text(文本,用于呈现一段信息)

《鸿蒙应用开发实战》未使用的组件:

marquee:跑马灯组件,用于展示一段单行滚动的文字

qecode:生成并显示二维码。

silder:滑动条组件,用来快速调节设置值,如音量、亮度等

switch:开关选择器,通过开关,开启或关闭某个功能》

还有一些具体的注意事项我把他放到了第二点,尤其是DevEco新老版本不一样的地方需要诸君多多注意!

完结撒花 诸君共勉!学习继续 强国有我!

附上自己敲的代码

注:该文都是自己学习过程的笔记,侵删。

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com

 

责任编辑:jianghua 来源: 鸿蒙社区
相关推荐

2021-06-30 09:27:58

鸿蒙HarmonyOS应用

2021-03-08 15:00:14

鸿蒙HarmonyOS应用

2021-03-03 15:47:51

HarmonyOS应用开发物联网

2020-11-09 11:56:49

HarmonyOS

2021-01-11 11:04:49

鸿蒙HarmonyOS应用开发

2022-08-09 16:01:24

应用开发鸿蒙

2022-08-15 22:09:37

设备开发开发笔记

2020-09-28 15:13:04

鸿蒙

2021-06-24 09:32:00

鸿蒙HarmonyOS应用

2021-02-07 12:08:39

鸿蒙HarmonyOS应用开发

2021-09-23 14:41:58

鸿蒙HarmonyOS应用

2021-07-05 14:29:28

鸿蒙HarmonyOS应用

2022-08-25 21:46:51

网络通讯应用开发

2021-02-03 09:59:02

鸿蒙HarmonyOS应用开发

2021-01-19 12:33:32

鸿蒙HarmonyOS应用开发

2021-01-19 10:09:02

鸿蒙HarmonyOS应用

2022-08-15 22:20:46

应用开发华为IoT平台

2021-01-14 09:50:26

鸿蒙HarmonyOSAPP

2024-03-26 15:19:36

鸿蒙应用开发开发工具

2020-11-05 10:05:25

App
点赞
收藏

51CTO技术栈公众号