device-clock-guide.md 12.5 KB
Newer Older
D
duangavin123 已提交
1 2 3 4 5 6 7 8 9 10 11
# Development Guidelines on Clock Apps<a name="EN-US_TOPIC_0000001115417926"></a>

## Overview<a name="section11522349121115"></a>

This document describes how to quickly set up a development environment \(using the Hi3516D V300 development board\) and develop a clock app running on OpenHarmony. You can click  [here](https://gitee.com/openharmony/app_samples/tree/master/common/Clock)  to obtain the sample code.

The clock app displays the current time, as shown in the following figure.

**Figure  1**  Clock display effect<a name="fig7763172132019"></a>  


D
duangavin123 已提交
12
![](figures/clock.png)
D
duangavin123 已提交
13 14 15

## Preparations<a name="section6592121861218"></a>

16
Download and install DevEco Studio. For details, see the  [HUAWEI DevEco Studio User Guide](../../application-dev/quick-start/deveco-studio-user-guide-for-openharmony.md). 
D
duangavin123 已提交
17 18 19 20 21

## How to Develop<a name="section19901741111312"></a>

The Clock app displays the current time through a clock face and numbers.

D
duangavin123 已提交
22
As shown in  [Figure 1 Clock display effect](#fig7763172132019), the UI consists of two parts:
D
duangavin123 已提交
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170

-   Clock face area: displays a dynamic analog clock whose hands rotate accurately.
-   Digital time area: displays the current time in numerals.

To build such an app, we can create a page that has a flexible layout with two rows vertically arranged. The development procedure is as follows:

1.  Add a root component  **<div\>**  to the  **.hml**  file. Note that each  **.hml**  file can contain only one root component. The sample code is as follows:

    ```
    <div class="container">
    </div>
    ```

    **class="container"**  indicates the style used by the component. The  **container**  is a style class defined in the  **index.css**  file.

    ```
    .container {     
        flex-direction: column;
        justify-content: center;
        align-items: center;
        width: 100%;
        height: 100%;
    }
    ```

    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.

2.  Implement clock hand rotation using the  **<stack\>**  component. The  **<stack\>**  component provides a stack container where child components are successively stacked and the latter one overwrites the previous one.

    Add a stack container to the root component. The sample code is as follows:

    ```
    <div class="container">    
        <stack class="stack">
            <image src="/common/clock_bg.png" class="clock-bg"></image> <!--Set the clock face image.-->
            <image src="/common/hour_hand.png" class="clock-hand"
                   style="transform : rotate({{ hour * 30 + minute / 2 }}deg);"></image> <!--Set the hour hand image. (hour * 30) indicates that the hour hand rotates 30 degrees every hour.  (minute / 2) indicates the rotation degrees per minute.-->
            <image src="/common/minute_hand.png" class="clock-hand"
                   style="transform : rotate({{ minute * 6 + second / 10 }}deg);"></image> <!--Set the minute hand image. (minute * 6) indicates that the minute hand rotates 6 degrees every minute. (second / 10) indicates the rotation degrees per second.-->
            <image src="/common/second_hand.png" class="clock-hand"
                   style="transform : rotate({{ second * 6 }}deg);"></image> <!--Set the second hand image. (second * 6) indicates that the second hand rotates 6 degrees per second.-->
       </stack>
    </div>
    ```

    **style="transform: rotate\(\{\{ second \* 6 \}\}deg\)**  sets the rotation event of a component.  **transform**  translates, rotates, or scales an image.  **rotate**  rotates an image. You can set an image to rotate around its x-axis or y-axis.

    Set attributes, such as the height, width, and position, of the stack component in the CSS file. The sample code is as follows:

    ```
    .stack {
        flex-direction: column;
        justify-content: center;
        align-items: center;
        width: 100%;
        height: 50%;
    }
    ```

    Set attributes, such as the height and width, of the clock-bg component in the CSS file. The sample code is as follows:

    ```
    .clock-bg {
        width: 80%;
        height: 80%;
        object-fit: scale-down;
    }
    ```

    Set attributes, such as the height and width of the hour, minute, and second hands, of the clock-hand component in the CSS file. The sample code is as follows:

    ```
    .clock-hand {
        width: 25%;
        height: 65%;
        object-fit: contain;
    }
    ```

    Add a timer in the  **index.js**  file to update the hour, minute, and second variables in real time so that the time can be automatically updated on the app UI. The sample code is as follows:

    ```
    export default {
        timer: undefined,
        // Define parameters.
        data: {
          hour: 0,   // Define hours.
          minute: 0, // Define minutes.
          second: 0  // Define seconds.
        },
        onInit () {
            this.updateTime();
            this.timer = setInterval(this.updateTime, 1000)// Set the timer to 1 second.
        },  
        updateTime: function () {       
            var nowTime = new Date()    
            this.hour = nowTime.getHours()    
            this.minute = nowTime.getMinutes()   
            this.second = nowTime.getSeconds()    
            if (this.hour < 10) {        
                this.hour = '0' + this.hour    
            }  
            if (this.minute < 10) {       
                this.minute = '0' + this.minute   
            }    
            if (this.second < 10) {      
                this.second = '0' + this.second   
            }
        },
    }
    ```

3.  Display the current time in numerals under the analog clock. Add the text component at the end of the root layout. The following example shows the UI structure:

    ```
    <text class="digit-clock"> {{ hour }}:{{ minute }}:{{ second }}</text>
    ```

    class=**"digit-clock"**  sets the height, width, and font size of the component. The sample code is as follows:

    ```
    .digit-clock {    
        font-size: 58px;   
        width: 100%;
        margin-top: 0px;
        text-align: center;
    }
    ```

4.  Set the style, animation effect, and dynamic data binding for all components. The complete sample code is as follows:
    -   **index.hml**

        ```
        <div class="container">
            <stack class="stack">
                <image src="/common/clock_bg.png" class="clock-bg"></image>
                <image src="/common/hour_hand.png" class="clock-hand"
                       style="transform : rotate({{ hour * 30 + minute / 2 }}deg);"></image>
                <image src="/common/minute_hand.png" class="clock-hand"
                       style="transform : rotate({{ minute * 6 + second / 10 }}deg);"></image>
                <image src="/common/second_hand.png" class="clock-hand"
                       style="transform : rotate({{ second * 6 }}deg);"></image>
            </stack>
            <text class="digit-clock">{{ hour }}:{{ minute }}:{{ second }}</text>
        </div>
        ```

    -   **index.css**
D
duangavin123 已提交
171

D
duangavin123 已提交
172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209
        ```
        .container {
            flex-direction: column;
            justify-content: center;
            align-items: center;
            width: 100%;
            height: 100%;
        }
        
        .stack {
            flex-direction: column;
            justify-content: center;
            align-items: center;
            width: 100%;
            height: 50%;
        }
        
        .digit-clock {
            font-size: 58px;
            width: 100%;
            margin-top: 0px;
            text-align: center;
        }
        
        .clock-bg {
            width: 80%;
            height: 80%;
            object-fit: scale-down;
        }
        
        .clock-hand {
            width: 25%;
            height: 65%;
            object-fit: contain;
        }
        ```

    -   **index.js**
D
duangavin123 已提交
210

D
duangavin123 已提交
211
        A  **.js**  file is used to implement logic interactions of the clock app. The following  **.js**  file implements the function of periodically obtaining the system time.
D
duangavin123 已提交
212

D
duangavin123 已提交
213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249
        ```
        export default {
            timer: undefined,
            data: {
                hour: 0,
                minute: 0,
                second: 0
            },
            onInit() {
                this.updateTime()
                this.timer = setInterval(this.updateTime, 1000)
            },
            updateTime: function () {
                var nowTime = new Date()
                this.hour = nowTime.getHours()
                this.minute = nowTime.getMinutes()
                this.second = nowTime.getSeconds()
                if (this.hour < 10) {
                    this.hour = '0' + this.hour
                }
                if (this.minute < 10) {
                    this.minute = '0' + this.minute
                }
                if (this.second < 10) {
                    this.second = '0' + this.second
                }
            },
            onDestroy() {
                clearInterval(this.timer);
            }
        }
        ```



## Signing and Packaging<a name="section10601181101516"></a>

250
After finishing writing the app code, you need to sign and package the app before running it on a real device. For details, see  [Signing and Packaging Guide](https://developer.harmonyos.com/en/docs/documentation/doc-guides/ohos-debugging-and-running-0000001263040487#section17660437768).
D
duangavin123 已提交
251 252 253

## Running on the Real Device<a name="section092721731511"></a>

D
duangavin123 已提交
254
Before you install the app and run it on the development board, install the DevEco Device Tool by following operations provided in  [HUAWEI DevEco Device Tool User Guide](https://device.harmonyos.com/en/docs/ide/user-guides/service_introduction-0000001050166905). Burn OpenHarmony into the development board, and run it on the board. For details about how to build, burn, and run an image, see . After the image is running normally and the system is started properly, perform the following steps to install or uninstall the app:
D
duangavin123 已提交
255 256 257 258 259 260 261 262 263 264 265 266

1.  Obtain the HDC client from the following path:

    ```
    developtools/hdc_standard/prebuilt/windows/hdc_std.exe
    ```

    Change the HDC client name to  **hdc.exe**  and add the path above to the system environment variable  **path**.

2.  Open the  **cmd**  window, and run the following commands to push the HAP file to the device directory, and install it:

    ```
267
    hdc install clock.hap
D
duangavin123 已提交
268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316
    ```

3.  Run the following command to start the app.  **ohos.samples.clock**  indicates the app package name, and  **MainAbility**  indicates the ability started by the app.

    ```
    hdc shell aa start -d 123 -a ohos.samples.clock.MainAbility -b ohos.samples.clock
    ```

4.  \(Optional\) Run the following command to uninstall the app.  **ohos.samples.clock**  indicates the app package name.

    ```
    hdc shell bm uninstall -n ohos.samples.clock
    ```


## FAQs<a name="section1122413460153"></a>

### hdc\_std Fails to Connect to a Device<a name="section1922725151614"></a>

-   **Symptom**

    **\[Empty\]**  is displayed in the output after the  **hdc\_std list targets**  command is run.

-   **Possible Causes and Solutions**
    1.  The device fails to be identified.

        Check whether  **HDC Device**  exists in the universal serial bus device of the device manager. If  **HDC Device**  does not exist, the device cannot be connected. In this case, remove and then insert the device or burn the latest image for the device.

    2.  hdc\_std works improperly.

        Run the  **hdc kill**  or  **hdc start -r**  command to kill or restart the HDC service, and then run the  **hdc list targets**  command to check whether device information is obtained.

    3.  hdc\_std does not match the device.

        If the latest image is burnt for the device, hdc\_std must also be of the latest version. As hdc\_std is updated continuously, obtain hdc\_std of the latest version from the  **developtools\_hdc\_standard**  repository in the  **prebuilt**  directory.



### hdc\_std Fails to Run<a name="section15657547131615"></a>

-   **Symptom**

    The  **hdc\_std.exe**  file does not run after being clicked.

-   **Possible Causes and Solutions**

    **hdc\_std.exe**  requires no installation and can be directly used on a disk. It can also be added to environment variables. Open the  **cmd**  window and run the  **hdc\_std**  command to use  **hdc\_std.exe**.