04-UI组件介绍和实际应用(下)

通过前几章的学习,我们已经对 OpenHarmony 的一些基础组件和布局方式有了初步的了解。在本章中,我们将结合多个组件的使用,通过一个数字时钟的完整示例,进一步巩固学习的内容。 本示例会展示如何使用 OpenHarmony 的动画功能、状态管理,以及滑动条和切换开关等组件,帮助您更好地理解和应用 ArkUI 框架。

1、示例演示

经过前几章的学习,我们对一些基本的组件也有大概的一些了解,若想了解更多可以到鸿蒙官网了解更多

小技巧

鸿蒙官网

我们将实现一个动态数字时钟,时钟能够显示实时更新的时间,并包含以下:

核心功能: 时间动态更新:通过动画实现数字的翻页效果。 亮度调节:使用滑动条组件动态设置屏幕亮度。 全屏模式切换:使用开关组件实现全屏模式和常规模式的切换。 关键组件:

Text:用于显示时钟数字。 Slider:滑动条,用于调整屏幕亮度。 Toggle:开关,用于全屏切换功能。 动画功能:实现数字翻页效果。

Clock

1.1、数字闹钟主要部分代码:

 1        //修改时间
 2        changeTime(): Array<number> {
 3            const time = new Date()
 4            const hour = time.getHours()
 5            const hourOne = Math.floor(hour / 10)
 6            const hourTwo = hour % 10
 7            const minutesOne = Math.floor(time.getMinutes() / 10)
 8            const minutesTwo = time.getMinutes() % 10
 9            const secondsOne = Math.floor(time.getSeconds() / 10)
10            const secondsTwo = time.getSeconds() % 10
11            return [hourOne, hourTwo, minutesOne, minutesTwo, secondsOne, secondsTwo]
12        }
13
14        @Builder box(num : number) {
15            Column() {
16            Divider()
17                .zIndex(5)
18                .strokeWidth(2)
19                .color(Color.White)
20                .position({ x: 0, y: '50%' })
21
22            Text(`${this.timeOne[num]}`)
23                .zIndex(1)
24                .height(108)
25                .width('100%')
26                .borderRadius(8)
27                .fontWeight(700)
28                .padding({ top: 0 })
29                .fontSize(90)
30                .position({ x: 0, y: 0 })
31                .fontColor(Color.White)
32                .fontFamily('Monospace')
33                .backgroundColor($r('app.color.text_bg'))
34                .textAlign(TextAlign.Center)
35
36            Text(`${this.timeTwo[num]}`)
37                .zIndex(2)
38                .height(64)
39                .width('100%')
40                .fontWeight(700)
41                .borderRadius(8)
42                .padding({ top: 3 })
43                .fontSize(90)
44                .position({ x: 0, y: 0 })
45                .fontColor(Color.White)
46                .fontFamily('Monospace')
47                .backgroundColor($r('app.color.text_bg'))
48                .textAlign(TextAlign.Center)
49
50            Text(`${this.timeThree[num]}`)
51                .zIndex(4)
52                .height(64)
53                .width('100%')
54                .fontWeight(700)
55                .borderRadius(8)
56                .padding({ top: 3 })
57                .fontSize(90)
58                .position({ x: 0, y: 0 })
59                .fontColor(Color.White)
60                .fontFamily('Monospace')
61                .textAlign(TextAlign.Center)
62                .backgroundColor($r('app.color.text_bg'))
63                .rotate({
64                x: 1,
65                y: 0,
66                z: 0,
67                centerX: '50%',
68                centerY: '100%',
69                angle: this.angleOne[num]
70                })
71
72            Text(`${this.timeFour[num]}`)
73                .zIndex(3)
74                .height(108)
75                .width('100%')
76                .fontWeight(700)
77                .borderRadius(8)
78                .padding({ top: 0 })
79                .fontSize(90)
80                .position({ x: 0, y: 0 })
81                .fontColor(Color.White)
82                .fontFamily('Monospace')
83                .backgroundColor($r('app.color.text_bg'))
84                .textAlign(TextAlign.Center)
85                .rotate({
86                x: 1,
87                y: 0,
88                z: 0,
89                centerX: '50%',
90                centerY: '50%',
91                angle: this.angleTwo[num]
92                })
93            }
94            .height(108)
95            .width('50%')
96        }

1.2、动画旋转部分代码:

 1        animationOne(i : number): void {
 2            animateTo({
 3            duration: 250,
 4            delay: 0,
 5            iterations: 1,
 6            onFinish: () => {
 7                this.animationTwo(i)
 8                this.angleOne[i] = 0
 9            }
10            }, () => this.angleOne[i] = 90)
11        }
12
13        animationTwo(i : number): void {
14            animateTo({
15            duration: 250,
16            delay: 0,
17            iterations: 1,
18            onFinish: () => {
19                this.angleTwo[i] = -90
20            }
21            }, () => this.angleTwo[i] = 0)
22        }

1.3、全屏部分代码:

1        this.isFullScreen = !this.isFullScreen
2            try {
3                let win = await window.getLastWindow(getContext(this))
4                let names = this.isFullScreen ? [] : ['status', 'navigation']
5                await win.setWindowSystemBarEnable(names as Array<'status' | 'navigation'>)
6                }

完整代码展示 :

  1        import { brightness } from '@kit.BasicServicesKit';
  2        import { LockSwitch } from './LockSwitch';
  3        import { window } from '@kit.ArkUI';
  4
  5        @Entry
  6        @Component
  7        struct Index {
  8        @State message: string = 'Hello World';
  9        @State timeOne: Array<number> = []
 10        @State timeTwo: Array<number> = []
 11        @State timeThree: Array<number> = []
 12        @State timeFour: Array<number> = []
 13        @State angleOne: Array<number> = [0, 0, 0, 0, 0, 0]
 14        @State angleTwo: Array<number> = [-90, -90, -90, -90, -90, -90]
 15
 16        @State isFullScreen: boolean = false
 17        @State inSetValue: number = 40
 18
 19
 20        aboutToAppear() {
 21            const arr = this.changeTime()
 22            this.timeOne = [...arr]
 23            this.timeTwo = [...arr]
 24            this.timeThree = [...arr]
 25            this.timeFour = [...arr]
 26            setInterval(() => {
 27            const time = new Date()
 28            if (this.timeOne[5] != time.getSeconds() % 10) {
 29                const arr = this.changeTime()
 30                for (let i = 0;i < 6; i++) {
 31                if (arr[i] != this.timeFour[i]) {
 32                    this.timeFour[i] = arr[i]
 33                    this.animationOne(i)
 34                    setTimeout(() => {
 35                    this.timeTwo[i] = arr[i]
 36                    }, 100)
 37                    setTimeout(() => {
 38                    this.timeThree[i] = arr[i]
 39                    }, 150)
 40                    setTimeout(() => {
 41                    this.timeOne[i] = arr[i]
 42                    }, 240)
 43                }
 44                }
 45            }
 46            }, 1000)
 47        }
 48
 49        animationOne(i : number): void {
 50            animateTo({
 51            duration: 250,
 52            delay: 0,
 53            iterations: 1,
 54            onFinish: () => {
 55                this.animationTwo(i)
 56                this.angleOne[i] = 0
 57            }
 58            }, () => this.angleOne[i] = 90)
 59        }
 60
 61        animationTwo(i : number): void {
 62            animateTo({
 63            duration: 250,
 64            delay: 0,
 65            iterations: 1,
 66            onFinish: () => {
 67                this.angleTwo[i] = -90
 68            }
 69            }, () => this.angleTwo[i] = 0)
 70        }
 71
 72        setBrightness(): void {
 73            brightness.setValue(this.inSetValue)
 74        }
 75
 76        //修改时间
 77        changeTime(): Array<number> {
 78            const time = new Date()
 79            const hour = time.getHours()
 80            const hourOne = Math.floor(hour / 10)
 81            const hourTwo = hour % 10
 82            const minutesOne = Math.floor(time.getMinutes() / 10)
 83            const minutesTwo = time.getMinutes() % 10
 84            const secondsOne = Math.floor(time.getSeconds() / 10)
 85            const secondsTwo = time.getSeconds() % 10
 86            return [hourOne, hourTwo, minutesOne, minutesTwo, secondsOne, secondsTwo]
 87        }
 88
 89        @Builder box(num : number) {
 90            Column() {
 91            Divider()
 92                .zIndex(5)
 93                .strokeWidth(2)
 94                .color(Color.White)
 95                .position({ x: 0, y: '50%' })
 96
 97            Text(`${this.timeOne[num]}`)
 98                .zIndex(1)
 99                .height(108)
100                .width('100%')
101                .borderRadius(8)
102                .fontWeight(700)
103                .padding({ top: 0 })
104                .fontSize(90)
105                .position({ x: 0, y: 0 })
106                .fontColor(Color.White)
107                .fontFamily('Monospace')
108                .backgroundColor($r('app.color.text_bg'))
109                .textAlign(TextAlign.Center)
110
111            Text(`${this.timeTwo[num]}`)
112                .zIndex(2)
113                .height(64)
114                .width('100%')
115                .fontWeight(700)
116                .borderRadius(8)
117                .padding({ top: 3 })
118                .fontSize(90)
119                .position({ x: 0, y: 0 })
120                .fontColor(Color.White)
121                .fontFamily('Monospace')
122                .backgroundColor($r('app.color.text_bg'))
123                .textAlign(TextAlign.Center)
124
125            Text(`${this.timeThree[num]}`)
126                .zIndex(4)
127                .height(64)
128                .width('100%')
129                .fontWeight(700)
130                .borderRadius(8)
131                .padding({ top: 3 })
132                .fontSize(90)
133                .position({ x: 0, y: 0 })
134                .fontColor(Color.White)
135                .fontFamily('Monospace')
136                .textAlign(TextAlign.Center)
137                .backgroundColor($r('app.color.text_bg'))
138                .rotate({
139                x: 1,
140                y: 0,
141                z: 0,
142                centerX: '50%',
143                centerY: '100%',
144                angle: this.angleOne[num]
145                })
146
147            Text(`${this.timeFour[num]}`)
148                .zIndex(3)
149                .height(108)
150                .width('100%')
151                .fontWeight(700)
152                .borderRadius(8)
153                .padding({ top: 0 })
154                .fontSize(90)
155                .position({ x: 0, y: 0 })
156                .fontColor(Color.White)
157                .fontFamily('Monospace')
158                .backgroundColor($r('app.color.text_bg'))
159                .textAlign(TextAlign.Center)
160                .rotate({
161                x: 1,
162                y: 0,
163                z: 0,
164                centerX: '50%',
165                centerY: '50%',
166                angle: this.angleTwo[num]
167                })
168            }
169            .height(108)
170            .width('50%')
171        }
172
173        build() {
174            Column() {
175            Row() {
176                Row({ space: 2 }) {
177                this.box(0)
178                this.box(1)
179                }
180                .width('30%')
181                .height('30%')
182
183                Image($r('app.media.dot'))
184                .width(20)
185                .height(50)
186
187                Row({ space: 2 }) {
188                this.box(2)
189                this.box(3)
190                }
191                .width('30%')
192                .height('30%')
193
194                Image($r('app.media.dot'))
195                .width(20)
196                .height(50)
197
198                Row({ space: 2 }) {
199                this.box(4)
200                this.box(5)
201                }
202                .width('30%')
203                .height('30%')
204            }
205            .id('currentTimeBox')
206            .width('50%')
207            .height('50%')
208
209
210            Column({ space: 10 }) {
211                Divider()
212                .strokeWidth(5)
213                .color($r('app.color.divider_bg'))
214
215                Row() {
216                Text($r("app.string.fullScreen")).fontSize(18)
217
218                Blank()
219
220                Toggle({ type: ToggleType.Switch, isOn: this.isFullScreen })
221                    .switchPointColor(0xe5ffffff)
222                    .onChange(async () => {
223                    this.isFullScreen = !this.isFullScreen
224                    try {
225                        let win = await window.getLastWindow(getContext(this))
226                        let names = this.isFullScreen ? [] : ['status', 'navigation']
227                        await win.setWindowSystemBarEnable(names as Array<'status' | 'navigation'>)
228                    } catch (err) {
229                        console.info(`setFullScreen fail, code = ${err.code}`)
230                    }
231                    })
232                }
233                .width('90%')
234                .height(62)
235                .borderRadius(24)
236                .margin({ top: 10 })
237                .backgroundColor(Color.White)
238                .padding({ left: '3%', right: '3%' })
239
240                Divider()
241                .strokeWidth(5)
242                .color($r('app.color.divider_bg'))
243
244                Row() {
245                Lock()
246                }
247                .width('90%')
248                .height(62)
249                .borderRadius(24)
250                .margin({ top: 10 })
251                .backgroundColor(Color.White)
252                .padding({ left: '3%', right: '3%' })
253
254                Divider()
255                .strokeWidth(5)
256                .color($r('app.color.divider_bg'))
257
258                Row() {
259                Text($r("app.string.brightness"))
260                    .fontSize(18)
261
262                Slider({
263                    value: this.inSetValue,
264                    min: 0,
265                    max: 255,
266                    step: 5,
267                    style: SliderStyle.OutSet
268                })
269                    .id('brightness')
270                    .width('90%')
271                    .showTips(false)
272                    .showSteps(false)
273                    .blockColor(0xCCCCCC)
274                    .trackColor(Color.Black)
275                    .selectedColor(0xCCCCCC)
276                    .onChange((value: number, mode: SliderChangeMode) => {
277                    this.inSetValue = value
278                    this.setBrightness()
279                    })
280                }
281                .width('90%')
282                .height(62)
283                .borderRadius(24)
284                .margin({ top: 10 })
285                .backgroundColor(Color.White)
286                .padding({ left: '3%', right: '3%' })
287
288                Divider()
289                .strokeWidth(5)
290                .color($r('app.color.divider_bg'))
291            }
292            .height('100%')
293
294            }
295            .width('100%')
296            .height('100%')
297            .backgroundColor('#F1F3F5')
298            .justifyContent(FlexAlign.Center)
299        }
300        }
301
302        @Component
303        struct Lock {
304        @State isComTime: boolean = true
305
306        build() {
307            Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
308            Column() {
309                LockSwitch({ isComTime: $isComTime })
310            }
311            .width('100%')
312            }
313        }
314        }

源码地址 :示例源码