1# Building the Home Page<a name="EN-US_TOPIC_0000001054927705"></a> 2 3The application home page displays air quality information of different cities. The home page provides two screens \(for two information bars\), which can be added as required. Each screen displays the air quality information of one city, including the Air Quality Index \(AQI\), city name, pollution level, update time, and data source. 4 5The home page of [AirQuality](device-camera-visual-overview.md) consists of three parts: 6 7- Title bar: displays the page title and provides an exit button. The title bar is fixed at the top of the page. 8- Information bar: displays air quality information. Multiple information bars can be added based on user requirements and support looping scroll. 9- Indicator bar: shows the position of the current screen among all screens. The indicator bar is fixed at the bottom of the page. 10 11The following steps describe how to build the home page with a flexible layout that has three rows vertically arranged. 12 131. Add a root **<div\>** to the **.hml** file. Note that each **.hml** file can contain only one root component. The sample code is as follows: 14 15 ``` 16 <div class="container"> 17 </div> 18 ``` 19 20 **class="container"** indicates the style used by the component. The **container** is a style class defined in the **index.css** file. 21 22 ``` 23 .container { 24 flex-direction: column; 25 height: 480px; 26 width: 960px; 27 } 28 ``` 29 30 The height and width of the root component **<div\>** are set in the style class. Note that the height and width must be explicitly specified \(except for some components, such as **<text\>**\). Otherwise, the component may fail to display. In the **container** style class, the **flex-direction** attribute is set to **column**, which means that child components of **<div\>** are vertically arranged from top to bottom for implementing the flexible page layout. 31 322. Add the title bar. The title bar consists of an exit button and title text that are horizontally arranged. Add a **<div\>** to hold the title bar and set the **flex-direction** attribute to **row** to arrange the child components from left to right. Add an **<image\>** and a **<text\>** component in sequence. The sample code is as follows: 33 34 ``` 35 <div class="container"> 36 <div class="header" onclick="exitApp"> 37 <image class="back" src="common/ic_back.png"></image> 38 <text class="title"> 39 Air quality 40 </text> 41 </div> 42 </div> 43 ``` 44 45 Set component attributes, including the height, width, margin, and color. 46 47 ``` 48 .header { 49 width: 960px; 50 height: 72px; 51 } 52 .back { 53 width: 36px; 54 height: 36px; 55 margin-left: 39px; 56 margin-top: 23px; 57 } 58 .title { 59 width: 296px; 60 height: 40px; 61 margin-top: 20px; 62 margin-left: 21px; 63 color: #e6e6e6; 64 } 65 ``` 66 67 In the **.hml** file, **onclick="exitApp"** sets the click event for the **<div\>** component. When the click event is triggered, the **exitApp\(\)** function is executed. The example definition of **exitApp\(\)** in **index.js** is as follows: 68 69 ``` 70 exitApp() { 71 console.log('start exit'); 72 app.terminate(); 73 console.log('end exit'); 74 } 75 ``` 76 77 The **app.terminate\(\)** function is used to exit the program. Before using this function, you must import the **app** module by adding the following code at the beginning of **index.js**: 78 79 ``` 80 import app from '@system.app' 81 ``` 82 83 After the code is compiled, run the project on the simulator. The following figure shows the display effect. 84 85 **Figure 1** Title bar<a name="fig14273162465317"></a> 86 ![](figures/title-bar.png "title-bar") 87 883. The **<swiper\>** component is required to implement the switching between screens. 89 90 Add a **<swiper\>** to the root node. 91 92 ``` 93 <div class="container"> 94 <div class="header" onclick="exitApp"> 95 <image class="back" src="common/ic_back.png"></image> 96 <text class="title"> 97 Air quality 98 </text> 99 </div> 100 <swiper class="swiper" index="{{swiperPage}}" duration="500" onchange="swiperChange"> 101 </swiper> 102 </div> 103 ``` 104 105 - Use **class="**swiper**"** to set the height and width of the component. The sample code is as follows: 106 107 ``` 108 .swiper { 109 height: 385px; 110 width: 960px; 111 } 112 ``` 113 114 - **index="\{\{swiperPage\}\}" duration="500" onchange="swiperChange"** sets the component attribute and event. **duration="500"** indicates that the duration of the swiping animation is 500 ms. 115 - **index="\{\{swiperPage\}\}"** specifies the index of the child component of **<swiper\>**. **\{\{swiperPage\}\}** indicates that the index value is dynamically bound to the **swiperPage** variable in the JavaScript code. The index value changes with the **swiperPage** value. 116 - **onchange="swiperChange"** binds the change event of the **<swiper\>** component to the **swiperChange** function. The JavaScript code is as follows: 117 118 ``` 119 // Import the router module for page switching. 120 import router from'@system.router' 121 import app from '@system.app' 122 123 export default { 124 // Define parameters. 125 data: { 126 // By default, the first page is displayed. 127 swiperPage: 0 128 }, 129 onInit () { 130 }, 131 exitApp(){ 132 console.log('start exit'); 133 app.terminate(); 134 console.log('end exit'); 135 }, 136 // Swiping event, which saves the index value of the current <swiper>. The index value is saved to the swiperPage variable each time a swiping occurs. 137 swiperChange (e) { 138 this.swiperPage = e.index; 139 } 140 } 141 ``` 142 1434. Set the information about a city to be displayed on a screen. On each screen, information of different types is displayed using different components. 144 145 Add two **<stack\>** as child components \(directional layout\) to **<swiper\>**. Add **<text\>**, **<image\>**, **<progress\>**, and other components to each **<stack\>** to display the information. The following example shows the page structure: 146 147 ``` 148 <swiper class="swiper" index="{{swiperPage}}" duration="500" onchange="swiperChange"> 149 <!-- The first screen --> 150 <stack class="swiper"> 151 <text></text>------Air quality 152 <text></text>------City name 153 <progress></progress>-----Progress bar 154 <image></image>-------A cloud image 155 <text></text>--------AQI value 156 <text>AQI</text>------AQI 157 <div>--------AQI details 158 </div> 159 <div>--------Update time, website, and other information 160 </div> 161 </stack> 162 <!-- The second screen --> 163 <stack class="container"> 164 <text></text> 165 <text></text> 166 <progress></progress> 167 <image></image> 168 <text></text> 169 <text></text> 170 <div></div> 171 </stack> 172 </swiper> 173 ``` 174 175 After the code is compiled, the display effect on the simulator is as follows. 176 177 **Figure 2** Title bar and information bar<a name="fig177003454238"></a> 178 ![](figures/title-bar-and-information-bar.png "title-bar-and-information-bar") 179 1805. Add the indicator bar. Currently, the **<swiper\>** component does not support indicator settings. You need to implement a dots indicator by adding **<div\>** components and setting the style. Add a **<div\>** as a child component to the root node and set the style. Add two **<div\>** to the parent **<div\>**, set **border-radius** for the two child **<div\>**, and dynamically change the background colors of the **<div\>** components in the swiping event. 181 182 ``` 183 <div class="images"> 184 <div class="circle-div" style="background-color: {{iconcheckedColor}};"></div> 185 <div class="circle-div" style="background-color: {{iconUncheckedColor}};margin-left: 36px;"></div> 186 </div> 187 ``` 188 189 **Figure 3** Indicator bar<a name="fig767374119496"></a> 190 ![](figures/indicator-bar.png "indicator-bar") 191 1926. Set the style, animation effect, and dynamic data binding for all components. The complete sample code is as follows: 193 194 - **index.hml** 195 196 ``` 197 <div class="container"> 198 <div class="header" onclick="exitApp"> 199 <image class="back" src="common/ic_back.png"></image> 200 <text class="title"> 201 AirQuality 202 </text> 203 </div> 204 <swiper class="swiper" index="{{swiperPage}}" duration="500" onchange="swiperChange"> 205 <stack class="swiper"> 206 <text class="airquality" style="color:{{textColor1}};">{{airData[0].airQuality}} 207 </text> 208 <text class="location-text">{{airData[0].location}} 209 </text> 210 <progress class="circle-progress" style="color: {{textColor1}};background-Color: {{bgColor1}};" type="arc" 211 percent="{{percent1}}"></progress> 212 <image class="image" src="{{src1}}"></image> 213 <text class="aqi-value">{{airData[0].detailData}} 214 </text> 215 <text class="aqi"> 216 AQI 217 </text> 218 <div class="detail"> 219 <div class="text-wrapper"> 220 <text class="gas-name"> 221 CO 222 </text> 223 <text class="gas-value"> 224 100 225 </text> 226 </div> 227 <div class="text-wrapper"> 228 <text class="gas-name"> 229 NO2 230 </text> 231 <text class="gas-value"> 232 90 233 </text> 234 </div> 235 <div class="text-wrapper"> 236 <text class="gas-name"> 237 PM10 238 </text> 239 <text class="gas-value"> 240 120 241 </text> 242 </div> 243 <div class="text-wrapper"> 244 <text class="gas-name"> 245 PM2.5 246 </text> 247 <text class="gas-value"> 248 40 249 </text> 250 </div> 251 <div class="text-wrapper"> 252 <text class="gas-name"> 253 SO2 254 </text> 255 <text class="gas-value"> 256 150 257 </text> 258 </div> 259 <input class="btn" type="button" onclick="openDetail" value=" History"></input> 260 </div> 261 <div class="footer"> 262 <text class="update-time"> 263 Update Time: 10:38 264 </text> 265 <text class="info-source"> 266 From: tianqi.com 267 </text> 268 </div> 269 </stack> 270 <stack class="swiper"> 271 <text class="airquality" style="color: {{textColor2}};">{{airData[1].airQuality}} 272 </text> 273 <text class="location-text">{{airData[1].location}} 274 </text> 275 <progress class="circle-progress" style="color: {{textColor2}};background-Color: {{bgColor2}};" type="arc" 276 percent="{{percent2}}"></progress> 277 <image class="image" src="{{src2}}"></image> 278 <text class="aqi-value">{{airData[1].detailData}} 279 </text> 280 <text class="aqi"> 281 AQI 282 </text> 283 <div class="detail"> 284 <div class="text-wrapper"> 285 <text class="gas-name"> 286 CO 287 </text> 288 <text class="gas-value"> 289 10 290 </text> 291 </div> 292 <div class="text-wrapper"> 293 <text class="gas-name"> 294 NO2 295 </text> 296 <text class="gas-value"> 297 50 298 </text> 299 </div> 300 <div class="text-wrapper"> 301 <text class="gas-name"> 302 PM10 303 </text> 304 <text class="gas-value"> 305 60 306 </text> 307 </div> 308 <div class="text-wrapper"> 309 <text class="gas-name"> 310 PM2.5 311 </text> 312 <text class="gas-value"> 313 40 314 </text> 315 </div> 316 <div class="text-wrapper"> 317 <text class="gas-name"> 318 SO2 319 </text> 320 <text class="gas-value"> 321 150 322 </text> 323 </div> 324 <input class="btn" type="button" onclick="openDetail" value=" History"></input> 325 </div> 326 <div class="footer"> 327 <text class="update-time"> 328 Update Time: 10:38 329 </text> 330 <text class="info-source"> 331 From: tianqi.com 332 </text> 333 </div> 334 </stack> 335 </swiper> 336 <div class="images"> 337 <div class="circle-div" style="background-color: {{iconcheckedColor}};"></div> 338 <div class="circle-div" style="background-color: {{iconUncheckedColor}};margin-left: 36px;"></div> 339 </div> 340 </div> 341 ``` 342 343 - **index.css** 344 345 A **.css** file contains many classes. Each class defines the position, size, font, color, and background color of a component. Each child component is added to its parent component, and the style file of the parent component affects how the child component will be displayed. 346 347 ``` 348 .aqi-value { 349 text-align: center; 350 font-size: 65px; 351 color: #f0ffff; 352 width: 156px; 353 height: 92px; 354 top: 134px; 355 left: 210px; 356 } 357 .aqi { 358 text-align: center; 359 color: #a2c4a2; 360 width: 156px; 361 height: 45px; 362 top: 90px; 363 left: 210px; 364 } 365 .airquality { 366 top: 222px; 367 text-align: center; 368 width: 156px; 369 height: 45px; 370 left: 210px; 371 } 372 .image { 373 top: 285px; 374 left: 274px; 375 width: 32px; 376 height: 32px; 377 } 378 .location-text { 379 text-align: center; 380 color: #ffffff; 381 width: 200px; 382 height: 52px; 383 font-size: 40px; 384 left: 380px; 385 top: 16px; 386 } 387 .container { 388 flex-direction: column; 389 height: 480px; 390 width: 960px; 391 } 392 .circle-progress { 393 center-x: 128px; 394 center-y: 128px; 395 radius: 128px; 396 startAngle: 198; 397 totalAngle: 320; 398 strokeWidth: 24px; 399 width: 256px; 400 height: 256px; 401 left: 160px; 402 top: 58px; 403 } 404 .detail { 405 width: 256px; 406 height: 265px; 407 left: 544px; 408 top: 58px; 409 flex-direction: column; 410 } 411 .text-wrapper { 412 width: 256px; 413 height: 35px; 414 margin-top: 6px; 415 } 416 .gas-name { 417 width: 128px; 418 height: 35px; 419 text-align: left; 420 } 421 .gas-value { 422 width: 128px; 423 height: 35px; 424 text-align: right; 425 } 426 .btn { 427 width: 180px; 428 height: 50px; 429 margin-top: 6px; 430 margin-left: 38px; 431 background-color: #1a1a1a; 432 color: #1085CE; 433 } 434 .footer { 435 top: 326px; 436 width: 960px; 437 height: 28px; 438 } 439 .header { 440 width: 960px; 441 height: 72px; 442 } 443 .back { 444 width: 36px; 445 height: 36px; 446 margin-left: 39px; 447 margin-top: 23px; 448 } 449 .title { 450 width: 296px; 451 height: 40px; 452 margin-top: 20px; 453 margin-left: 21px; 454 color: #e6e6e6; 455 } 456 .swiper { 457 height: 385px; 458 width: 960px; 459 } 460 .images { 461 width: 60px; 462 height: 15px; 463 margin-left: 450px; 464 } 465 .update-time { 466 width: 480px; 467 height: 28px; 468 font-size: 20px; 469 color: #A9A9A9; 470 text-align: right; 471 } 472 .info-source { 473 width: 450px; 474 height: 28px; 475 font-size: 20px; 476 color: #A9A9A9; 477 text-align: left; 478 margin-left: 24px; 479 } 480 .circle-div { 481 width: 12px; 482 height: 12px; 483 border-radius: 6px; 484 } 485 ``` 486 487 - **index.js** 488 489 A **.js** file is used to implement interaction logic of your application. In the **.js** file of the home page, implement page switching and enable text content and progress bar color to change dynamically according to AQI values. 490 491 ``` 492 // Import router and app modules. 493 import router from '@system.router' 494 import app from '@system.app' 495 496 export default { 497 data: { 498 // Bind data. 499 textColor1: '#00ff00', 500 textColor2: '#00ff00', 501 bgColor1: '#669966', 502 bgColor2: '#669966', 503 swiperPage: 0, 504 percent1: 40, 505 percent2: 90, 506 iconUncheckedColor: '#262626', 507 iconcheckedColor: '#ffffff', 508 iconcheckedBR: '6px', 509 src1: 'common/cloud_green.png', 510 src2: 'common/cloud_green.png', 511 airData: [{ 512 location: 'Dongguan', 513 airQuality: 'Good', 514 detailData: 40 515 }, { 516 location: 'Shenzhen', 517 airQuality: 'Polluted', 518 detailData: 90 519 }] 520 }, 521 onInit () { 522 // Set the font, background color, and background image for different value ranges. 523 if(this.airData[0].detailData > 100){ 524 this.src1 = 'common/cloud_red.png'; 525 this.textColor1 = '#ff0000'; 526 this.bgColor1 = '#9d7462'; 527 } else if(50 < this.airData[0].detailData && this.airData[0].detailData <= 100){ 528 this.src1 = 'common/cloud_yellow.png'; 529 this.textColor1 = '#ecf19a'; 530 this.bgColor1 = '#9d9d62'; 531 } 532 if(this.airData[1].detailData > 100){ 533 this.src2 = 'common/cloud_red.png'; 534 this.textColor2 = '#ff0000'; 535 this.bgColor2 = '#9d7462'; 536 } else if(50 < this.airData[1].detailData && this.airData[1].detailData <= 100){ 537 this.src2 = 'common/cloud_yellow.png'; 538 this.textColor2 = '#ecf19a'; 539 this.bgColor2 = '#9d9d62'; 540 } 541 if(this.selectedCityIndex){ 542 this.swiperPage = this.selectedCityIndex; 543 if(this.swiperPage == 0){ 544 this.iconcheckedColor = '#ffffff'; 545 this.iconUncheckedColor = '#262626'; 546 }else{ 547 this.iconcheckedColor = '#262626'; 548 this.iconUncheckedColor = '#ffffff'; 549 } 550 } 551 }, 552 // Switch to the details page. 553 openDetail () { 554 router.replace({ 555 uri: 'pages/detail/detail', 556 params: {selectedCityIndex:this.swiperPage} 557 }); 558 }, 559 // Exit the application. 560 exitApp(){ 561 console.log('start exit'); 562 app.terminate(); 563 console.log('end exit'); 564 }, 565 // Define the swiping event. Change the indicator dots when the user swipes the screen. 566 swiperChange (e) { 567 this.swiperPage = e.index; 568 if(e.index == 0){ 569 this.iconcheckedColor = '#ffffff'; 570 this.iconUncheckedColor = '#262626'; 571 }else{ 572 this.iconcheckedColor = '#262626'; 573 this.iconUncheckedColor = '#ffffff'; 574 } 575 } 576 } 577 ``` 578 579 580