【鸿蒙HarmonyOS Next App实战开发】​​ArkUI时钟界面实现解析:动态双模式时钟与沉浸式体验​

在鸿蒙next系统上,通过ArkTS写了个时钟显示页面,集成在【图影工具箱】应用中,应用商店可以下载使用。

这个页面实现起来比较简单,就是左边一个模拟时钟,右边一个数字时钟(包含时间和日期的文字),每秒更新一次模拟时钟和数字时钟。

本文基于鸿蒙ArkUI框架,实现了一个支持​​模拟/数字双模式显示​​、​​手势交互​​与​​动态主题切换​​的时钟应用。以下从技术架构、核心功能与创新交互三个维度展开解析。


​一、项目架构与技术栈​
  1. ​基础框架​

    • 使用ArkUI声明式开发范式(基于TypeScript),通过@Entry@Component装饰器定义页面组件。
    • 状态管理:@State驱动UI动态更新(如时间文本、时钟缩放比例、背景色)。
  2. ​依赖模块​

    import { common } from '@kit.AbilityKit';  // 系统能力库
    import { window } from '@kit.ArkUI';       // 窗口管理
    import { AnalogClockComponent } from './AnalogClockComponent'; // 自定义模拟时钟组件
    • ​工具类封装​​:
      • DateUtil:时间格式化(getFormatDateStr生成HH:mm:ssyyyy年MM月dd日)。
      • AppUtil:设备控制(息屏保持、强制横屏)。

​二、核心功能实现​
​1. 双模式时钟动态切换​
  • ​数字时钟​​:通过Text组件动态绑定时间与日期:

    @State timeText: string = '';  // 时间文本(HH:mm:ss)
    @State dateText: string = '';  // 日期文本(yyyy年MM月dd日)

    每秒更新数据:

    setInterval(() => this.load(), 1000); // 定时更新
  • ​模拟时钟​​:封装为独立组件AnalogClockComponent

    if (this.showClock) {AnalogClockComponent().scale({ x: this.clockScale, y: this.clockScale }) // 支持缩放.gesture(PinchGesture().onActionUpdate((event) => { // 捏合手势调整缩放比例(0.5~1.5倍)this.clockScale = Math.max(0.5, Math.min(1.5, event.scale * this.lastClockScale));}))
    }
​2. 交互设计​
  • ​显隐控制​​:顶部按钮切换模拟时钟显示状态:
    Button().onClick(() => this.showClock = !this.showClock)
  • ​主题切换​​:点击屏幕切换黑/白主题:
    .onClick(() => {this.flag = !this.flag;this.fontColor = this.flag ? TimePage.blackColor : TimePage.whiteColor;this.bgColor = this.flag ? TimePage.whiteColor : TimePage.greyColor;
    })
  • ​动画优化​​:黑白主题切换时添加缓动动画:
    Text(this.timeText).animation({ duration: 2000, curve: Curve.EaseOut })
​3. 设备适配与性能​
  • ​横屏沉浸式体验​​:
    AppUtil.setPreferredOrientation(window.Orientation.AUTO_ROTATION_LANDSCAPE);
  • ​保持不息屏​​:
    AppUtil.setWindowKeepScreenOn(true);

​三、关键技术点解析​
  1. ​状态驱动UI更新​

    • @State变量(如timeTextbgColor)变化自动触发UI重渲染。
    • 通过setInterval更新状态,实现每秒刷新时间。
  2. ​手势识别与动画​

    • ​捏合缩放​​:PinchGesture监听手势事件,动态计算缩放比例。
    • ​主题切换动画​​:页面背景色与文字颜色变化时应用2000ms渐变动画。
  3. ​组件化设计​

    • 模拟时钟独立封装为AnalogClockComponent,通过Props控制尺寸与缩放,符合高内聚原则。
    • 工具类DateUtil解耦时间逻辑,提升代码复用性。

​四、优化策略与设计理念​
  1. ​视觉层次设计​

    • ​主次分明​​:数字时钟使用100px大字体突出时间,日期文本使用30px小字体。
    • ​色彩对比​​:深灰背景(#fefefe)与白色文字确保可读性,夜间模式切换为深色文字+白色背景。
  2. ​响应式交互​

    • 手势操作实时反馈(捏合缩放),限制缩放范围避免UI变形。
    • 控件位置优化:控制按钮置于右上角,避免遮挡核心内容。
  3. ​性能与功耗​

    • 页面不可见时(onPageHide)清除定时器,减少资源占用。
    • 横屏模式适配多种设备尺寸,通过Stack+Row/Column布局保证元素对齐。

​五、扩展方向​
  1. ​多时区支持​​:扩展DateUtil,增加时区切换功能。
  2. ​动态背景​​:根据时间自动切换日出/日落主题色。

​结语​

本文实现的ArkUI时钟界面,通过​​状态驱动​​、​​手势交互​​与​​组件化设计​​,平衡了功能性与视觉体验。其设计模式可复用于其他实时数据展示场景(如天气仪表盘、健身数据统计)。未来可结合鸿蒙分布式能力,实现跨设备时钟同步控制。


​设计原则总结​​:

原则实现方式
​信息直观性​双模式时钟互补显示
​操作便捷性​手势缩放+一键切换
​视觉舒适性​动态主题+缓动动画
​性能优化​定时器生命周期管理

源码中的AnalogClockComponent实现可参考《ArkUI自定义组件之模拟时》,重点利用Canvas绘图与旋转动画实现指针效果。

具体代码如下:

import { common } from '@kit.AbilityKit';
import { window } from '@kit.ArkUI';
import { AppUtil } from './Utils/AppUtil';
import { DateUtil } from './Utils/DateUtil';
import { AnalogClockComponent } from './ClockPage/AnalogClockComponent';@Entry
@Component
struct TimePage {context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext;intervalID: number = -1;@State timeText: string = '';@State dateText: string = '';@State showClock: boolean = true;@State lastClockScale: number = 1.35;@State clockScale: number = 1.35;bigFontSize: number = 100;smallFontSize: number = 30;static readonly whiteColor: string = '#fefefe';static readonly greyColor: string | Resource = $r('app.color.body_color');static readonly blackColor: string | Resource = '#000';@State bgColor: string | Resource = TimePage.greyColor;@State fontColor: string | Resource = TimePage.whiteColor;@State flag: boolean = falsenowDate = Date.now();load() {this.nowDate = Date.now();this.timeText = DateUtil.getFormatDateStr(this.nowDate, "HH:mm:ss");this.dateText = DateUtil.getFormatDateStr(this.nowDate, "yyyy年MM月dd日")}onPageShow(): void {this.load();this.intervalID = setInterval(() => {this.load();}, 1000);AppUtil.setWindowKeepScreenOn(true);AppUtil.setPreferredOrientation(window.Orientation.AUTO_ROTATION_LANDSCAPE);}onPageHide(): void {clearInterval(this.intervalID);}build() {Stack({ alignContent: Alignment.Top }) {// 主要内容区域Row() {if (this.showClock) {// 模拟时钟组件Column() {AnalogClockComponent().width('60%').aspectRatio(1)}.scale({ x: this.clockScale, y: this.clockScale }).width('30%').height('100%').justifyContent(FlexAlign.Center).align(Alignment.Center).margin({ left: 30 }).gesture(PinchGesture().onActionStart((event: GestureEvent) => {this.lastClockScale = this.clockScale;}).onActionUpdate((event: GestureEvent) => {this.clockScale = Math.max(0.5, Math.min(1.5, event.scale * this.lastClockScale));}))}// 数字时间显示Column() {Text(this.timeText).fontSize(this.bigFontSize).fontColor(this.fontColor).animation({duration: 2000,curve: Curve.EaseOut,iterations: 1,playMode: PlayMode.Normal})Text(this.dateText).fontSize(this.smallFontSize).fontColor(this.fontColor).animation({duration: 2000,curve: Curve.Ease,iterations: 1,playMode: PlayMode.Normal})}.layoutWeight(1).height('100%').justifyContent(FlexAlign.Center)}.width('100%').height('100%')// 顶部控制栏Row() {Button() {Image(this.showClock ? $r('app.media.ic_visibility_off') : $r('app.media.ic_visibility')).width(24).height(24).fillColor(this.fontColor).opacity(0.3)}.width(48).height(48).borderRadius(24).backgroundColor('transparent').onClick(() => {this.showClock = !this.showClock;})}.width('100%').justifyContent(FlexAlign.End).padding({ right: 20, top: 20 })}.onClick(() => {if (this.flag) {this.fontColor = TimePage.whiteColor;this.bgColor = TimePage.greyColor;} else {this.fontColor = TimePage.blackColor;this.bgColor = TimePage.whiteColor;}this.flag = !this.flag;}).backgroundColor(this.bgColor).animation({duration: 2000,curve: Curve.Ease,iterations: 1,playMode: PlayMode.Normal}).width('100%').height('100%')}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/86121.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/86121.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ios签名错误的解决办法

另一种最常见的解决方案。在终端中运行以下命令。您应该添加自己的钥匙串名称和密码。security lock-keychain temp.keychainsecurity unlock-keychain -pp ssw0rd temp.keychain在这种情况下,使用钥匙串名称为“temp”,其密码为“p ssw0rd”。此外&am…

C#读取OPCUA节点数据

本人第一次接触OPCUA,如有不对的地方望指正,获取的是公司的OPCUA服务器的数据 方式一: 测试环境: window11 vs2022 OPCFoundation.NetStandard.Opc.Ua .net framework 4.8 (2025-06-23 经过测试,.net8也可以使用这套.net …

OpenCV计算机视觉实战(11)——边缘检测详解

OpenCV计算机视觉实战(11)——边缘检测详解 0. 前言1. Sobel 算子与方向梯度1.1 Sobel 算子简介1.2 实现过程 2. Laplacian 边缘检测2.1 Laplacian 算子简介2.2 实现过程 3. Canny 算法3.1 Canny 算法简介3.2 实现过程 小结系列链接 0. 前言 边缘检测能…

哈尔滨idc服务器租用-青蛙云

在数字化浪潮汹涌的当下,企业对于服务器的需求愈发强烈。哈尔滨作为东北地区重要的经济文化中心,其 IDC 服务器租用市场也呈现出蓬勃发展的态势。众多企业在寻求 IDC 服务器租用时,青蛙云凭借自身显著优势脱颖而出,成为众多用户的…

Zephyr 系统深入解析:SoC 支持包结构与中断调度器调优实践

本文将全面深入讲解 Zephyr RTOS 的 SoC 支持包设计架构(SoC Series / SoC Variant)、中断系统实现、调度器原理、时间片与优先级调优技巧,以及如何在实际项目中构建自定义 SoC 支持包、实现高效的调度器策略和系统性能优化。全文超过 5000 字…

FPGA基础 -- Verilog 结构建模之模块参数值

Verilog 中模块参数值(parameter)的使用,这是结构建模和模块可配置设计的核心机制,广泛应用于 总线宽度配置、流水线级数、功能开关、模块复用 等场景。 一、什么是模块参数值(parameter) parameter 是 Ver…

Skrill是什么?中国用户能用吗?安全吗?完整指南

什么是Skrill? Skrill 前身为 Moneybookers,成立于 2001 年,总部位于英国伦敦,目前隶属于 Paysafe 集团。作为一个多功能电子支付平台,Skrill 支持全球 100 多个国家和地区、40 多种货币,被广泛用于&#…

java+vue+SpringBoo校园部门资料管理系统(程序+数据库+报告+部署教程+答辩指导)

源代码数据库LW文档(1万字以上)开题报告答辩稿ppt部署教程代码讲解代码时间修改工具 技术实现 开发语言:后端:Java 前端:vue框架:springboot数据库:mysql 开发工具 JDK版本:JDK1.…

Java中的Map实现类详解

Java中的Map实现类详解 Java集合框架提供了多种Map接口的实现,每种实现都有其特定的使用场景和特点。以下是主要的Map实现类及其特性分析: 1. 通用Map实现 HashMap 特点:基于哈希表的实现,允许null键和null值线程安全&#xf…

Pytorch Lightning 进阶 1 - 梯度检查点(Gradient Checkpointing)

梯度检查点(Gradient Checkpointing)是一种在深度学习训练中优化显存使用的技术,尤其适用于处理大型模型(如Transformer架构)时显存不足的情况。下面用简单的例子解释其工作原理和优缺点: 核心原理 深度学…

SpreadJS 迷你图:数据趋势可视化的利器

引言 在数据处理和分析领域,直观地展示数据趋势对于理解数据和做出决策至关重要。迷你图作为一种简洁而有效的数据可视化方式,在显示数据趋势方面发挥着重要作用,尤其在与他人共享数据时,能够快速传达关键信息。SpreadJS 作为一款…

GESP2024年12月认证C++一级( 第三部分编程题(1)温度转换)

参考程序1&#xff1a; #include <cstdio> using namespace std;int main() {double K;scanf("%lf", &K);double C K - 273.15; //转换为摄氏温度 double F 32 C * 1.8; //转换为华氏温度 if (F > 212) //条件判断 print…

从零开始手写redis(18)缓存淘汰算法 FIFO 优化

项目简介 大家好&#xff0c;我是老马。 Cache 用于实现一个可拓展的高性能本地缓存。 有人的地方&#xff0c;就有江湖。有高性能的地方&#xff0c;就有 cache。 v1.0.0 版本 以前的 FIFO 实现比较简单&#xff0c;但是 queue 循环一遍删除的话&#xff0c;性能实在是太…

用Zynq实现脉冲多普勒雷达信号处理:架构、算法与实现详解

用Zynq实现脉冲多普勒雷达信号处理:架构、算法与实现详解 脉冲多普勒(PD)雷达是现代雷达系统的核心技术之一,广泛应用于机载火控、气象监测、交通监控等领域。其核心优势在于能在强杂波背景下检测运动目标,并精确测量其径向速度。本文将深入探讨如何利用Xilinx Zynq SoC(…

OpenCV CUDA模块设备层-----线程块级别的一个内存填充工具函数blockFill()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 在同一个线程块&#xff08;thread block&#xff09;内&#xff0c;将 [beg, end) 范围内的数据并行地填充为指定值 value。 它使用了 CUDA 线程…

SAP-ABAP:如何查询 SAP 事务码(T-Code)被包含在哪些权限角色或权限对象中

要查询 SAP 事务码&#xff08;T-Code&#xff09;被包含在哪些权限角色或权限对象中&#xff0c;可使用以下专业方法&#xff1a; &#x1f50d; 1. 通过权限浏览器 (SUIM) - 最推荐 事务码&#xff1a;SUIM (权限信息系统) 操作步骤&#xff1a; 执行 SUIM → 选择 “角色…

MySQL 多列 IN 查询详解:语法、性能与实战技巧

在 MySQL 中&#xff0c;多列 IN 查询是一种强大的筛选工具&#xff0c;它允许通过多字段组合快速过滤数据。相较于传统的 OR 连接多个条件&#xff0c;这种语法更简洁高效&#xff0c;尤其适合批量匹配复合键或联合字段的场景。本文将深入解析其用法&#xff0c;并探讨性能优化…

自由学习记录(63)

编码全称&#xff1a;AV1&#xff08;Alliance for Open Media Video 1&#xff09;。 算力消耗大&#xff1a;目前&#xff08;截至 2025 年中&#xff09;软件解码 AV1 的 CPU 开销非常高&#xff0c;如果没有专门的硬件解码单元&#xff0c;播放高清视频时会很吃 CPU&#…

日本生活:日语语言学校-日语作文-沟通无国界(4)-题目:喜欢读书

日本生活&#xff1a;日语语言学校-日语作文-沟通无国界&#xff08;4&#xff09;-题目&#xff1a;喜欢读书 1-前言2-作文原稿3-作文日语和译本&#xff08;1&#xff09;日文原文&#xff08;2&#xff09;对应中文&#xff08;3&#xff09;对应英文 4-老师评语5-自我感想&…

C++优化程序的Tips

转自个人博客 1. 避免创建过多中间变量 过多的中间变量不利于代码的可读性&#xff0c;还会增加内存的使用&#xff0c;而且可能导致额外的计算开销。 将用于同一种情况的变量统一管理&#xff0c;可以使用一种通用的变量来代替多个变量。 2. 函数中习惯使用引用传参而不是返…