开发首页

应用首页主要展示当前城市的空气质量概况。首页总共有两屏,每屏显示一个城市的空气质量信息:主要包括AQI指数、城市名称等,并且AQI指数值能够以环形进度条动画的形式展示出来。

  1. 实现城市空气质量信息的两屏左右滑动,需要使用“swiper”组件。

    在hml文件中添加一个根节点swiper,注意每个hml文件中有且只能有一个根节点,代码片段如下:

    1. <swiper class="container" style="left:253px;" index="{{swiperPage}}" duration="500" onchange="swiperChange">
    2. </swiper>
    • class=”container”表示组件使用的样式,container是index.css文件中的一个样式类,代码如下:

      1. .container{
      2. height: 454px;
      3. width: 454px;
      4. }

      这个样式类的作用是设置组件的高度和宽度。注意在应用开发中,必须显式指定组件的高度和宽度,否则组件可能无法显示。

  1. - index="\{\{swiperPage\}\}" duration="500" onchange="swiperChange" 这些代码用来设置组件的属性和事件。其中,duration="500" 表示设置swiper的页面滑动的动画时长为500ms
  2. - index="\{\{swiperPage\}\}"设置了swiper子组件索引值,\{\{swiperPage\}\}这种写法表示index的值是和js代码中的swiperPage变量动态绑定的,index的值会随着swiperPage变动而改变。
  3. - onchange="swiperChange" 设置了swiper组件的change事件和函数swiperChange绑定,对应的js代码如下:
  4. ```
  5. //引入router模块,用户页面跳转
  6. import router from'@system.router'
  7. export default {
  8. //定义参数
  9. data: {
  10. swiperPage:0 //默认是第一页
  11. },
  12. onInit () {
  13. },
  14. //swiper滑动回调事件,保存当前swiper的index值,每次滑动都会将index值保存在swiperPage变量中
  15. swiperChange (e) {
  16. this.swiperPage = e.index;
  17. }
  18. }
  19. ```
  1. 设置每个城市信息为一屏,在每一屏内,要展示4种信息,分别要使用不同的控件进行展示。

    在swiper中添加两个子组件stack,每个stack组件内分别添加text、image、progress组件来显示对应的信息 ,hml文件如下:

    1. <!--根组件为swiper,只支持一个根组件-->
    2. <swiper class="container" style="left:253px;" index="{{swiperPage}}" duration="500" onchange="swiperChange">
    3. <!--第一屏-->
    4. <stack class="container">
    5. <text></text>------城市
    6. <text></text>------空气质量
    7. <progress></progress>-----进度条
    8. <image></image>-------云朵图片
    9. <text></text>--------AQI数值
    10. <text>AQI</text>------AQI
    11. </stack>
    12. <!--第二屏-->
    13. <stack class="container">
    14. <text></text>
    15. <text></text>
    16. <progress></progress>
    17. <image></image>
    18. <text></text>
    19. <text></text>
    20. </stack>
    21. </swiper>
  2. 所有组件设置样式、动画效果和数据动态绑定,完整代码如下所示:

    • index.hml文件
    1. <!--根组件为swiper,只支持一个根组件-->
    2. <swiper class="container" style="left:253px;" index="{{swiperPage}}" duration="500" onchange="swiperChange">
    3. <!--第一屏-->
    4. <stack class="container">
    5. <!--显示空气质量和当前城市-->
    6. <text class="airquality" style="color:{{textColor1}};">{{airData[0].airQuality}}</text>
    7. <text class="location-text">{{airData[0].location}}</text>
    8. <!--根据AQI的值,显示动画效果,通过在js中动态改变percent1的值来实现-->
    9. <progress class="circleProgress"style="color:{{textColor1}};background-Color:{{bgColor1}};"type="arc"onclick="openDetail"percent="{{percent1}}"></progress>
    10. <image class="image"src="{{src1}}"></image>
    11. <!--空气质量指数,动态获取绑定数据-->
    12. <text class="pm25-value">{{airData[0].detailData}}</text>
    13. <text class="pm25-name">AQI</text>
    14. </stack>
    15. <!--第二屏-->
    16. <stack class="container">
    17. <text class="airquality"style="color:{{textColor2}};">{{airData[1].airQuality}}</text>
    18. <text class="location-text">{{airData[1].location}}</text>
    19. <progress class="circleProgress"style="color: {{textColor2}};background-Color:{{bgColor2}};"type="arc"onclick="openDetail"percent="{{percent2}}"></progress>
    20. <image class="image"src="{{src2}}"></image>
    21. <text class="pm25-value">{{airData[1].detailData}}</text>
    22. <text class="pm25-name">AQI</text>
    23. </stack>
    24. </swiper>
    • index.css文件

    css文件中定义了许多class,每个class用于定义组件的位置、大小、字体、颜色、背景色等信息。同时,每一个子组件都叠加在父组件中,也就是说父组件的样式会影响子组件的呈现。

    1. .pm25-value{
    2. text-align:center;
    3. font-size:38px;
    4. color:#f0ffff;
    5. width:454px;
    6. height:50px;
    7. top:275px;
    8. }
    9. .pm25-name{
    10. text-align:center;
    11. color:#a2c4a2;
    12. width:454px;
    13. height:50px;
    14. top:335px;
    15. }
    16. .location-text{
    17. text-align:center;
    18. color:#f0ffff;
    19. width:454px;
    20. height:50px;
    21. top:20px;
    22. }
    23. .container{
    24. height: 454px;
    25. width: 454px;;
    26. }
    27. .circleProgress{
    28. centerX:227px;
    29. centerY:250px;
    30. radius:180px;
    31. startAngle:198;
    32. totalAngle:320;
    33. strokeWidth:45;
    34. width:454px;
    35. height:454px;
    36. }
    37. .image{
    38. top:390px;
    39. left:217px;
    40. width:32px;
    41. height:32px;
    42. }
    43. .airquality{
    44. top:220px;
    45. text-align: center;
    46. width:454px;
    47. height:40px;
    48. }
    • index.js:

    js文件主要用于实现App应用的逻辑交互。在本页面js文件中,需要实现如下功能:根据数值动态改变文字、进度条颜色;国际化功能;页面跳转;播放动画。

    1. //引入router模块,用户页面跳转
    2. import router from'@system.router'
    3. export default {
    4. //定义参数
    5. data: {
    6. textColor1:'#00ff00',//文字颜色
    7. textColor2:'#00ff00',
    8. bgColor1:'#669966',//背景颜色
    9. bgColor2:'#669966',
    10. swiperPage:0,
    11. percent1:0,//进度条进度
    12. percent2:0,
    13. src1:'common/cloud_green.png',
    14. src2:'common/cloud_green.png',
    15. airData: [{
    16. location: 'HangZhou',
    17. airQuality: 'Good',
    18. detailData: 10
    19. }, {
    20. location: 'ShangHai',
    21. airQuality: 'Unhealth',
    22. detailData:90
    23. }]
    24. },
    25. onInit () {
    26. //国际化处理,通过$t函数获取对应的国际化内容,国际化文件请自行添加配置
    27. this.airData[0].location = this.$t(this.airData[0].location);
    28. this.airData[1].location = this.$t(this.airData[1].location);
    29. this.airData[0].airQuality = this.$t(this.airData[0].airQuality);
    30. this.airData[1].airQuality = this.$t(this.airData[1].airQuality);
    31. if(this.airData[0].detailData > 100){ //根据指标值显示不同的颜色问题和图片
    32. this.src1 = "common/cloud_red.png";
    33. this.textColor1 = '#ff0000';//显示红色文字
    34. this.bgColor1 = '#9d7462';
    35. } else if(50 < this.airData[0].detailData && this.airData[0].detailData <= 100){
    36. this.src1 = "common/cloud_yellow.png";
    37. this.textColor1 = '#ecf19a';//显示黄色文字
    38. this.bgColor1 = '#9d9d62';
    39. }
    40. if(this.airData[1].detailData > 100){
    41. this.src2 = "common/cloud_red.png";
    42. this.textColor2 = '#ff0000';
    43. this.bgColor2 = '#9d7462';
    44. } else if(50 < this.airData[1].detailData && this.airData[1].detailData <= 100){
    45. this.src2 = "common/cloud_yellow.png";
    46. this.textColor2 = '#ecf19a';
    47. this.bgColor2 = '#9d9d62';
    48. }
    49. if(this.selectedCityIndex){
    50. this.swiperPage = this.selectedCityIndex;
    51. }
    52. },
    53. onShow () { //页面显示的时候一些处理逻辑
    54. var self = this;
    55. var time = 1000/(self.airData[self.swiperPage].detailData);//1s播放完动画
    56. if(time == 0){
    57. time = 100;
    58. }
    59. //环形进度条动画效果,启动一个定时器,间隔一定的时间(时间根据AQI的值计算而来)改变一下进度条的进度,1s内完成动画的播放。
    60. var interval = setInterval(function () {
    61. if ((self.swiperPage==0?self.percent1:self.percent2) >= self.airData[self.swiperPage].detailData) {
    62. clearInterval(interval);
    63. return;
    64. }
    65. if(self.swiperPage == 0){
    66. self.percent1++;
    67. }else{
    68. self.percent2++
    69. }
    70. }, time)
    71. },
    72. //跳转到详情页
    73. openDetail () {
    74. router.replace({
    75. uri:'pages/detail/detail',
    76. params:{selectedCityIndex:this.swiperPage}//选中的城市
    77. });
    78. },
    79. //swiper滑动回调事件,保存当前swiper的index值,从详情页返回直接跳转到swiper的指定页
    80. swiperChange (e) {
    81. this.swiperPage = e.index;
    82. var self = this;
    83. var time = 1000/(self.airData[self.swiperPage].detailData);
    84. if(time == 0){
    85. time = 100;
    86. }
    87. //第一次滑动到页面,播放动画
    88. var interval = setInterval(function () {
    89. let percent = (self.swiperPage==0?self.percent1:self.percent2);
    90. if (percent >= self.airData[self.swiperPage].detailData) {
    91. clearInterval(interval);
    92. return;
    93. }
    94. if(self.swiperPage==0){
    95. self.percent1++;
    96. }else{
    97. self.percent2++;
    98. }
    99. }, time)
    100. }
    101. }