• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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