首页
  • GM-3568JHF
  • M4-R1
  • M5-R1
  • SC-3568HA
  • M-K1HSE
  • CF-NRS1
  • CF-CRA2
  • 1684XB-32T
  • 1684X-416T
  • C-3568BQ
  • C-3588LQ
  • GC-3568JBAF
  • C-K1BA
商城
  • English
  • 简体中文
首页
  • GM-3568JHF
  • M4-R1
  • M5-R1
  • SC-3568HA
  • M-K1HSE
  • CF-NRS1
  • CF-CRA2
  • 1684XB-32T
  • 1684X-416T
  • C-3568BQ
  • C-3588LQ
  • GC-3568JBAF
  • C-K1BA
商城
  • English
  • 简体中文
  • M4-R1

    • 一、简介

      • M4-R1简介
    • 二、快速上手

      • 01 OpenHarmony概述
      • 02 镜像烧录
      • 03 应用开发快速上手
      • 04 设备开发快速上手
    • 三、应用开发

      • 01 ArkUI

        • 1 ArkTS语言简介
        • 2 UI 组件-Row 容器介绍
        • 3 UI 组件-Column 容器介绍
        • 4 UI 组件-Text 组件
        • 5 UI 组件-Toggle 组件
        • 6 UI 组件-Slider 组件
        • 7 UI 组件-Animation 组件&Transition 组件
      • 02 资料获取

        • 1 OpenHarmony 官方资料
      • 03 开发须知

        • 1 Full-SDK替换教程
        • 2 引入和使用三方库
        • 3 HDC调试
        • 4 命令行恢复出厂模式
        • 5 升级App为system权限
      • 04 构建第一个应用

        • 1 构建第一个ArkTs应用-HelloWorld
      • 05 案例

        • 01 串口调试助手应用案例
        • 02 手写板应用案例
        • 03 数字时钟应用案例
        • 04 WIFI 信息获取应用案例
    • 四、设备开发

      • 01 环境搭建
      • 02 下载源码
      • 03 编译源码
    • 五、外设与接口

      • 树莓派接口
      • GPIO 接口
      • I2C 接口
      • SPI通信
      • PWM控制
      • 串口通讯
      • TF Card
      • 屏幕
      • 触摸
      • 音频
      • RTC
      • Ethernet
      • M.2
      • MINI-PCIE
      • Camera
      • WIFI&BT
      • 树莓派拓展板
    • 六、资料下载

      • 资料下载
  • M5-R1

    • 一、简介

      • M5-R1简介
    • 二、快速上手

      • 镜像烧录
      • 环境搭建
      • 下载源码
    • 三、外设与接口

      • 树莓派接口
      • GPIO 接口
      • I2C 接口
      • SPI通信
      • PWM控制
      • 串口通讯
      • TF Card
      • 屏幕
      • 触摸
      • 音频
      • RTC
      • Ethernet
      • M.2
      • MINI-PCIE
      • Camera
      • WIFI&BT
    • 四、资料下载

      • 资料下载

03 数字时钟应用案例

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

1. 示例演示

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

提示

鸿蒙官网

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

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

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

1.1 数字时钟主要部分代码

//修改时间
changeTime(): Array<number> {
	const time = new Date()
	const hour = time.getHours()
	const hourOne = Math.floor(hour / 10)
	const hourTwo = hour % 10
	const minutesOne = Math.floor(time.getMinutes() / 10)
	const minutesTwo = time.getMinutes() % 10
	const secondsOne = Math.floor(time.getSeconds() / 10)
	const secondsTwo = time.getSeconds() % 10
	return [hourOne, hourTwo, minutesOne, minutesTwo, secondsOne, secondsTwo]
}

@Builder box(num : number) {
	Column() {
	  Divider()
		.zIndex(5)
		.strokeWidth(2)
		.color(Color.White)
		.position({ x: 0, y: '50%' })

		Text(`${this.timeOne[num]}`)
			.zIndex(1)
			.height(108)
			.width('100%')
			.borderRadius(8)
			.fontWeight(700)
			.padding({ top: 0 })
			.fontSize(90)
			.position({ x: 0, y: 0 })
			.fontColor(Color.White)
			.fontFamily('Monospace')
			.backgroundColor($r('app.color.text_bg'))
			.textAlign(TextAlign.Center)

		Text(`${this.timeTwo[num]}`)
			.zIndex(2)
			.height(64)
			.width('100%')
			.fontWeight(700)
			.borderRadius(8)
			.padding({ top: 3 })
			.fontSize(90)
			.position({ x: 0, y: 0 })
			.fontColor(Color.White)
			.fontFamily('Monospace')
			.backgroundColor($r('app.color.text_bg'))
			.textAlign(TextAlign.Center)

		Text(`${this.timeThree[num]}`)
			.zIndex(4)
			.height(64)
			.width('100%')
			.fontWeight(700)
			.borderRadius(8)
			.padding({ top: 3 })
			.fontSize(90)
			.position({ x: 0, y: 0 })
			.fontColor(Color.White)
			.fontFamily('Monospace')
			.textAlign(TextAlign.Center)
			.backgroundColor($r('app.color.text_bg'))
			.rotate({
			  x: 1,
			  y: 0,
			  z: 0,
			  centerX: '50%',
			  centerY: '100%',
			  angle: this.angleOne[num]
			})

		Text(`${this.timeFour[num]}`)
			.zIndex(3)
			.height(108)
			.width('100%')
			.fontWeight(700)
			.borderRadius(8)
			.padding({ top: 0 })
			.fontSize(90)
			.position({ x: 0, y: 0 })
			.fontColor(Color.White)
			.fontFamily('Monospace')
			.backgroundColor($r('app.color.text_bg'))
			.textAlign(TextAlign.Center)
			.rotate({
			  x: 1,
			  y: 0,
			  z: 0,
			  centerX: '50%',
			  centerY: '50%',
			  angle: this.angleTwo[num]
			})
	}
	.height(108)
	.width('50%')
}

1.2 动画旋转部分代码

animationOne(i : number): void {
	animateTo({
		duration: 250,
		delay: 0,
		iterations: 1,
		onFinish: () => {
			this.animationTwo(i)
			this.angleOne[i] = 0
		}
	}, () => this.angleOne[i] = 90)
}

animationTwo(i : number): void {
	animateTo({
		duration: 250,
		delay: 0,
		iterations: 1,
		onFinish: () => {
			this.angleTwo[i] = -90
		}
	}, () => this.angleTwo[i] = 0)
}

1.3 全屏部分代码

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

2. 完整代码展示

import { brightness } from '@kit.BasicServicesKit';
import { LockSwitch } from './LockSwitch';
import { window } from '@kit.ArkUI';

@Entry
@Component
struct Index {
	@State message: string = 'Hello World';
	@State timeOne: Array<number> = []
	@State timeTwo: Array<number> = []
	@State timeThree: Array<number> = []
	@State timeFour: Array<number> = []
	@State angleOne: Array<number> = [0, 0, 0, 0, 0, 0]
	@State angleTwo: Array<number> = [-90, -90, -90, -90, -90, -90]

	@State isFullScreen: boolean = false
	@State inSetValue: number = 40


	aboutToAppear() {
		const arr = this.changeTime()
		this.timeOne = [...arr]
		this.timeTwo = [...arr]
		this.timeThree = [...arr]
		this.timeFour = [...arr]
		setInterval(() => {
		  const time = new Date()
		  if (this.timeOne[5] != time.getSeconds() % 10) {
			  const arr = this.changeTime()
			  for (let i = 0;i < 6; i++) {
			    if (arr[i] != this.timeFour[i]) {
				    this.timeFour[i] = arr[i]
				    this.animationOne(i)
				    setTimeout(() => {
				      this.timeTwo[i] = arr[i]
				    }, 100)
				    setTimeout(() => {
				      this.timeThree[i] = arr[i]
				    }, 150)
				    setTimeout(() => {
				      this.timeOne[i] = arr[i]
				    }, 240)
			    }
			  }
		  }
		}, 1000)
	}

	animationOne(i : number): void {
		animateTo({
		  duration: 250,
		  delay: 0,
		  iterations: 1,
		  onFinish: () => {
			  this.animationTwo(i)
			  this.angleOne[i] = 0
		  }
		}, () => this.angleOne[i] = 90)
	}

	animationTwo(i : number): void {
		animateTo({
		  duration: 250,
		  delay: 0,
		  iterations: 1,
		  onFinish: () => {
			  this.angleTwo[i] = -90
		  }
		}, () => this.angleTwo[i] = 0)
	}

	setBrightness(): void {
		brightness.setValue(this.inSetValue)
	}

	//修改时间
	changeTime(): Array<number> {
		const time = new Date()
		const hour = time.getHours()
		const hourOne = Math.floor(hour / 10)
		const hourTwo = hour % 10
		const minutesOne = Math.floor(time.getMinutes() / 10)
		const minutesTwo = time.getMinutes() % 10
		const secondsOne = Math.floor(time.getSeconds() / 10)
		const secondsTwo = time.getSeconds() % 10
		return [hourOne, hourTwo, minutesOne, minutesTwo, secondsOne, secondsTwo]
	}

	@Builder box(num : number) {
		Column() {
		Divider()
			.zIndex(5)
			.strokeWidth(2)
			.color(Color.White)
			.position({ x: 0, y: '50%' })

		Text(`${this.timeOne[num]}`)
			.zIndex(1)
			.height(108)
			.width('100%')
			.borderRadius(8)
			.fontWeight(700)
			.padding({ top: 0 })
			.fontSize(90)
			.position({ x: 0, y: 0 })
			.fontColor(Color.White)
			.fontFamily('Monospace')
			.backgroundColor($r('app.color.text_bg'))
			.textAlign(TextAlign.Center)

		Text(`${this.timeTwo[num]}`)
			.zIndex(2)
			.height(64)
			.width('100%')
			.fontWeight(700)
			.borderRadius(8)
			.padding({ top: 3 })
			.fontSize(90)
			.position({ x: 0, y: 0 })
			.fontColor(Color.White)
			.fontFamily('Monospace')
			.backgroundColor($r('app.color.text_bg'))
			.textAlign(TextAlign.Center)

		Text(`${this.timeThree[num]}`)
			.zIndex(4)
			.height(64)
			.width('100%')
			.fontWeight(700)
			.borderRadius(8)
			.padding({ top: 3 })
			.fontSize(90)
			.position({ x: 0, y: 0 })
			.fontColor(Color.White)
			.fontFamily('Monospace')
			.textAlign(TextAlign.Center)
			.backgroundColor($r('app.color.text_bg'))
			.rotate({
			x: 1,
			y: 0,
			z: 0,
			centerX: '50%',
			centerY: '100%',
			angle: this.angleOne[num]
			})

		Text(`${this.timeFour[num]}`)
			.zIndex(3)
			.height(108)
			.width('100%')
			.fontWeight(700)
			.borderRadius(8)
			.padding({ top: 0 })
			.fontSize(90)
			.position({ x: 0, y: 0 })
			.fontColor(Color.White)
			.fontFamily('Monospace')
			.backgroundColor($r('app.color.text_bg'))
			.textAlign(TextAlign.Center)
			.rotate({
			x: 1,
			y: 0,
			z: 0,
			centerX: '50%',
			centerY: '50%',
			angle: this.angleTwo[num]
			})
		}
		.height(108)
		.width('50%')
	}

	build() {
		Column() {
		  Row() {
			  Row({ space: 2 }) {
			    this.box(0)
			    this.box(1)
			  }
			  .width('30%')
			  .height('30%')

			  Image($r('app.media.dot'))
			  .width(20)
			  .height(50)

			  Row({ space: 2 }) {
			    this.box(2)
			    this.box(3)
			  }
			  .width('30%')
			  .height('30%')

			  Image($r('app.media.dot'))
			  .width(20)
			  .height(50)

			  Row({ space: 2 }) {
			    this.box(4)
			    this.box(5)
			  }
			  .width('30%')
			  .height('30%')
		  }
		  .id('currentTimeBox')
		  .width('50%')
		  .height('50%')


		  Column({ space: 10 }) {
			  Divider()
			  .strokeWidth(5)
			  .color($r('app.color.divider_bg'))

			  Row() {
			    Text($r("app.string.fullScreen")).fontSize(18)

			    Blank()

			    Toggle({ type: ToggleType.Switch, isOn: this.isFullScreen })
				  .switchPointColor(0xe5ffffff)
				  .onChange(async () => {
				    this.isFullScreen = !this.isFullScreen
				    try {
					    let win = await window.getLastWindow(getContext(this))
					    let names = this.isFullScreen ? [] : ['status', 'navigation']
					    await win.setWindowSystemBarEnable(names as Array<'status' | 'navigation'>)
				    } catch (err) {
					    console.info(`setFullScreen fail, code = ${err.code}`)
				    }
				  })
			  }
			  .width('90%')
			  .height(62)
			  .borderRadius(24)
			  .margin({ top: 10 })
			  .backgroundColor(Color.White)
			  .padding({ left: '3%', right: '3%' })

			  Divider()
			  .strokeWidth(5)
			  .color($r('app.color.divider_bg'))

			  Row() {
			    Lock()
			  }
			  .width('90%')
			  .height(62)
			  .borderRadius(24)
			  .margin({ top: 10 })
			  .backgroundColor(Color.White)
			  .padding({ left: '3%', right: '3%' })

			  Divider()
			  .strokeWidth(5)
			  .color($r('app.color.divider_bg'))

			  Row() {
			    Text($r("app.string.brightness"))
				  .fontSize(18)

			  Slider({
				  value: this.inSetValue,
				  min: 0,
				  max: 255,
				  step: 5,
				  style: SliderStyle.OutSet
			  })
				.id('brightness')
				.width('90%')
				.showTips(false)
				.showSteps(false)
				.blockColor(0xCCCCCC)
				.trackColor(Color.Black)
				.selectedColor(0xCCCCCC)
				.onChange((value: number, mode: SliderChangeMode) => {
				  this.inSetValue = value
				  this.setBrightness()
				})
			}
			.width('90%')
			.height(62)
			.borderRadius(24)
			.margin({ top: 10 })
			.backgroundColor(Color.White)
			.padding({ left: '3%', right: '3%' })

			Divider()
			.strokeWidth(5)
			.color($r('app.color.divider_bg'))
		}
		.height('100%')

		}
		.width('100%')
		.height('100%')
		.backgroundColor('#F1F3F5')
		.justifyContent(FlexAlign.Center)
	}
}

@Component
struct Lock {
	@State isComTime: boolean = true

	build() {
		Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
		  Column() {
			  LockSwitch({ isComTime: $isComTime })
		  }
		  .width('100%')
		}
	}
}

3. 案例源码及HAP包获取

3.1 案例源码获取

1)百度网盘资料中下载 Clock_API12.zip。 链接: 提取码:

CLOCK

备注:

项目路径:
ShimetaPi开源鸿蒙资料>SC-3568HA>05-开发资料>01-OpenHarmory 开发资料>APP Demo>Clock_API12.zip

2)解压压缩包后通过 DevEco Studio 打开工程即可查看源码。

3.2 案例 HAP 包获取

1)百度网盘资料中下载 Clock_API12.hap。 链接: 提取码:

CLOCK

备注:

文件路径:
ShimetaPi开源鸿蒙资料>SC-3568HA>05-开发资料>01-OpenHarmory 开发资料>APP Demo>Hap_Package>Clock_API12.hap

2)案例通过 HAP 进行安装的过程同前面的串口助手和手写板案例一致,此处不再赘述。

4. 案例功能介绍

该案例可实现一个实时显示时间的动画时钟;
单击全屏按钮可使其边框覆盖整个屏幕。

在 GitHub 上编辑此页
上次更新:
贡献者: jxc
Prev
02 手写板应用案例
Next
04 WIFI 信息获取应用案例