鸿蒙NEXT开发案例:世界时间表

【引言】

本案例将展示如何使用鸿蒙NEXT框架开发一个简单的世界时钟应用程序。该应用程序能够展示多个城市的当前时间,并支持搜索功能,方便用户快速查找所需城市的时间信息。在本文中,我们将详细介绍应用程序的实现思路,包括如何获取时区信息、更新城市时间、以及如何实现搜索高亮功能。

【环境准备】

• 操作系统:Windows 10

• 开发工具:DevEco Studio NEXT Beta1 Build Version: 5.0.3.806

• 目标设备:华为Mate60 Pro

• 开发语言:ArkTS

• 框架:ArkUI

• API版本:API 12

【实现思路】

1. 组件结构设计

我们的应用程序主要由两个核心组件构成:CityTimeInfo类和WorldClockApp组件。CityTimeInfo类用于存储每个城市的名称、当前时间和时区信息。WorldClockApp组件则负责管理城市时间列表、搜索功能以及用户界面。

2. 获取时区信息

在应用程序启动时,我们需要获取可用的时区信息。通过调用i18n.TimeZone.getAvailableIDs()方法,我们可以获取所有可用的时区ID。接着,我们使用这些ID创建CityTimeInfo实例,并将其添加到城市时间列表中。为了确保用户能够看到当前时间,我们还添加了北京的时间信息作为默认城市。

3. 更新时间逻辑

为了实时更新城市的当前时间,我们在updateAllCityTimes方法中实现了时间更新逻辑。通过获取系统的语言环境和相应的日历对象,我们可以根据城市的时区ID获取当前的年、月、日、时、分、秒,并将其格式化为字符串。这个方法会在页面显示时每秒调用一次,确保时间信息的准确性。

4. 搜索功能实现

为了提升用户体验,我们实现了搜索功能,允许用户通过输入关键词来筛选城市。在highlightSearchText方法中,我们对城市名称进行分段处理,将匹配的关键词高亮显示。通过这种方式,用户可以快速找到所需的城市,并且高亮的文本能够提供更好的视觉反馈。

5. 用户界面构建

最后,我们使用build方法构建用户界面。界面包括一个搜索框、城市名称和时间的显示区域。我们使用了Column和Row组件来布局,并通过设置样式属性来美化界面。滚动区域的实现使得用户可以方便地浏览多个城市的信息。

【完整代码】

import { i18n } from '@kit.LocalizationKit' // 导入国际化模块,用于处理多语言
import { inputMethod } from '@kit.IMEKit' // 导入输入法模块

@ObservedV2
  // 观察者装饰器,用于观察状态变化
class CityTimeInfo { // 定义城市时间信息类
  @Trace cityName: string = ""; // 城市名称,初始为空字符串
  @Trace currentTime: string = ""; // 当前时间,初始为空字符串
  timeZone: i18n.TimeZone; // 时区属性

  constructor(cityName: string, timeZone: i18n.TimeZone) { // 构造函数,接收城市名称和时区
    this.cityName = cityName; // 设置城市名称
    this.timeZone = timeZone; // 设置时区
  }

  @Trace isVisible: boolean = true; // 是否可见,初始为true
}

@Entry
  // 入口组件装饰器
@Component
  // 组件装饰器
struct WorldClockApp { // 定义世界时钟应用组件
  @State private searchText: string = ''; // 搜索文本,初始为空字符串
  @State private cityTimeList: CityTimeInfo[] = []; // 城市时间信息列表,初始为空数组
  private lineColor: string = "#e6e6e6"; // 边框颜色
  private titleBackgroundColor: string = "#f8f8f8"; // 标题背景色
  private textColor: string = "#333333"; // 文字颜色
  private basePadding: number = 4; // 内边距
  private lineWidth: number = 2; // 边框宽度
  private rowHeight: number = 50; // 行高
  private ratio: number[] = [1, 1]; // 列宽比例
  private textSize: number = 14; // 基础字体大小
  private updateIntervalId = 0; // 更新间隔ID

  updateAllCityTimes() { // 更新所有城市的时间
    const locale = i18n.System.getSystemLocale(); // 获取系统语言环境
    for (const cityTime of this.cityTimeList) { // 遍历城市时间列表
      const timeZoneId: string = cityTime.timeZone.getID(); // 获取时区ID
      const calendar = i18n.getCalendar(locale); // 获取日历对象
      calendar.setTimeZone(timeZoneId); // 设置日历的时区

      // 获取当前时间的各个部分
      const year = calendar.get("year").toString().padStart(4, '0'); // 年
      const month = calendar.get("month").toString().padStart(2, '0'); // 月
      const day = calendar.get("date").toString().padStart(2, '0'); // 日
      const hour = calendar.get("hour_of_day").toString().padStart(2, '0'); // 小时
      const minute = calendar.get("minute").toString().padStart(2, '0'); // 分钟
      const second = calendar.get("second").toString().padStart(2, '0'); // 秒

      // 更新城市的当前时间字符串
      cityTime.currentTime = `${year}年${month}月${day}日 ${hour}:${minute}:${second}`;
    }
  }

  onPageShow(): void { // 页面显示时的处理
    clearInterval(this.updateIntervalId); // 清除之前的定时器
    this.updateIntervalId = setInterval(() => { // 设置新的定时器
      this.updateAllCityTimes(); // 每秒更新所有城市的时间
    }, 1000);
  }

  onPageHide(): void { // 页面隐藏时的处理
    clearInterval(this.updateIntervalId); // 清除定时器
  }

  private highlightSearchText(cityTime: CityTimeInfo, keyword: string) { // 高亮搜索文本
    let text = cityTime.cityName // 获取城市名称

    if (!keyword) { // 如果没有关键词
      cityTime.isVisible = true // 设置城市可见
      return [text] // 返回城市名称
    }
    let segments: string[] = []; // 存储分段文本
    let lastMatchEnd: number = 0; // 上一个匹配结束的位置
    while (true) { // 循环查找关键词
      const matchIndex = text.indexOf(keyword, lastMatchEnd); // 查找关键词位置
      if (matchIndex === -1) { // 如果没有找到
        segments.push(text.slice(lastMatchEnd)); // 添加剩余文本
        break; // 退出循环
      } else {
        segments.push(text.slice(lastMatchEnd, matchIndex)); // 添加匹配前的文本
        segments.push(text.slice(matchIndex, matchIndex + keyword.length)); // 添加匹配的关键词
        lastMatchEnd = matchIndex + keyword.length; // 更新最后匹配结束位置
      }
    }
    cityTime.isVisible = (segments.indexOf(keyword) != -1) // 设置城市可见性
    return segments; // 返回分段文本
  }

  aboutToAppear() { // 组件即将出现时的处理
    const timeZoneIds: Array<string> = i18n.TimeZone.getAvailableIDs(); // 获取可用时区ID列表

    this.cityTimeList.push(new CityTimeInfo('北京 (中国)', i18n.getTimeZone())); // 添加北京的城市时间信息

    for (const id of timeZoneIds) { // 遍历时区ID
      const cityDisplayName = i18n.TimeZone.getCityDisplayName(id.split('/')[1], "zh-CN"); // 获取城市显示名称
      if (cityDisplayName) { // 如果城市名称存在
        this.cityTimeList.push(new CityTimeInfo(cityDisplayName, i18n.getTimeZone(id))); // 添加城市时间信息
      }
    }

    this.updateAllCityTimes(); // 更新所有城市的时间
  }

  build() { // 构建组件的UI
    Column({ space: 0 }) { // 创建一个垂直列
      Search({ value: $$this.searchText })// 创建搜索框
        .margin(this.basePadding)// 设置边距
        .fontFeature("\"ss01\" on") // 设置字体特性
      Column() { // 创建一个列
        Row() { // 创建一行
          Text('城市')// 显示“城市”文本
            .height('100%')// 高度占满
            .layoutWeight(this.ratio[0])// 设置布局权重
            .textAlign(TextAlign.Center)// 文本居中
            .fontSize(this.textSize)// 设置字体大小
            .fontWeight(600)// 设置字体粗细
            .fontColor(this.textColor) // 设置字体颜色
          Line().height('100%').width(this.lineWidth).backgroundColor(this.lineColor) // 创建分隔线
          Text('时间')// 显示“时间”文本
            .height('100%')// 高度占满
            .layoutWeight(this.ratio[1])// 设置布局权重
            .textAlign(TextAlign.Center)// 文本居中
            .fontSize(this.textSize)// 设置字体大小
            .fontWeight(600)// 设置字体粗细
            .fontColor(this.textColor) // 设置字体颜色
        }.height(this.rowHeight).borderWidth(this.lineWidth).borderColor(this.lineColor) // 设置行高和边框
        .backgroundColor(this.titleBackgroundColor) // 设置背景色
      }.width(`100%`).padding({ left: this.basePadding, right: this.basePadding }) // 设置列宽和内边距

      Scroll() { // 创建可滚动区域
        Column() { // 创建一个列
          ForEach(this.cityTimeList, (item: CityTimeInfo) => { // 遍历城市时间列表
            Row() { // 创建一行
              Text() { // 创建文本
                ForEach(this.highlightSearchText(item, this.searchText), (segment: string, index: number) => { // 高亮搜索文本
                  ContainerSpan() { // 创建容器
                    Span(segment)// 创建文本段
                      .fontColor(segment === this.searchText ? Color.White : Color.Black)// 设置字体颜色
                      .onClick(() => { // 点击事件
                        console.info(`高亮文本被点击:${segment}`); // 输出点击的文本
                        console.info(`点击索引:${index}`); // 输出点击的索引
                      });
                  }.textBackgroundStyle({
                    // 设置文本背景样式
                    color: segment === this.searchText ? Color.Red : Color.Transparent // 根据是否匹配设置背景色
                  });
                });
              }
              .height('100%') // 高度占满
              .layoutWeight(this.ratio[0]) // 设置布局权重
              .textAlign(TextAlign.Center) // 文本居中
              .fontSize(this.textSize) // 设置字体大小
              .fontColor(this.textColor) // 设置字体颜色

              Line().height('100%').width(this.lineWidth).backgroundColor(this.lineColor) // 创建分隔线
              Text(item.currentTime)// 显示当前时间
                .height('100%')// 高度占满
                .layoutWeight(this.ratio[1])// 设置布局权重
                .textAlign(TextAlign.Center)// 文本居中
                .fontSize(this.textSize)// 设置字体大小
                .fontColor(this.textColor) // 设置字体颜色
            }
            .height(this.rowHeight) // 设置行高
            .borderWidth({ left: this.lineWidth, right: this.lineWidth, bottom: this.lineWidth }) // 设置边框宽度
            .borderColor(this.lineColor) // 设置边框颜色
            .visibility(item.isVisible ? Visibility.Visible : Visibility.None) // 根据可见性设置显示状态
          })

        }.width(`100%`).padding({ left: this.basePadding, right: this.basePadding }) // 设置宽度和内边距
      }
      .width('100%') // 设置宽度占满
      .layoutWeight(1) // 设置布局权重
      .align(Alignment.Top) // 对齐方式
      .onScrollStart(() => { // 滚动开始事件
        this.onPageHide() // 页面隐藏处理
      })
      .onScrollStop(() => { // 滚动停止事件
        this.onPageShow() // 页面显示处理
      })
      .onTouch((event) => { // 触摸事件
        if (event.type == TouchType.Down) { // 如果是按下事件
          inputMethod.getController().stopInputSession() // 停止输入会话
        }
      })
    }
  }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Windows如何安装Php 7.4

一、进入官网&#xff0c;选择其他版本 https://windows.php.net/download/ 二、配置环境变量 将解压后的php 路径在系统环境变量中配置一下 cmd 后输入 php-v

yosys内部数据结构

一、参考链接 1.Yosys内部结构doxygen文件 yosys-master: RTLIL Namespace Reference 2.yosys内部结构介绍 https://yosyshq.readthedocs.io/projects/yosys/en/docs-preview-cellhelp/yosys_internals/formats/rtlil_rep.html 二、概览 图 1 网表核心数据结构 如图 1所示…

Java性能调优 - 多线程性能调优

锁优化 Synchronized 在JDK1.6中引入了分级锁机制来优化Synchronized。当一个线程获取锁时 首先对象锁将成为一个偏向锁&#xff0c;这样做是为了优化同一线程重复获取锁&#xff0c;导致的用户态与内核态的切换问题&#xff1b;其次如果有多个线程竞争锁资源&#xff0c;锁…

window的conda环境下espeak not installed on your system问题解决

1 问题描述 windows的conda环境下运行VITS2模型预处理&#xff0c;报出如下错误&#xff1a; Traceback (most recent call last):File "D:\ml\vits2\filelists.py", line 63, in <module>text_norm tokenizer(text_norm, Vocab, cleaners, languagehps.dat…

wine的使用方法

wine版本 所有分支&#xff0c;新的主要版本&#xff1a; wine-x.0 All branches, release candidates:各分支、候选版本&#xff1a; wine-x.0-rcn Stable branch updates: 稳定分支更新&#xff1a; wine-x.0.z Development branch updates: wine-x.y wine *.exe “更改目…

深度学习笔记26_糖尿病预测模型优化探索

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 | 接辅导、项目定制 一、我的环境 1.语言环境&#xff1a;Python 3.9 2.编译器&#xff1a;Pycharm 3.深度学习环境&#xff1a;TensorFlow 2.10.0 二、GPU设置…

深度学习的unfold操作

unfold&#xff08;展开&#xff09;是深度学习框架中常见的数据操作。与我们熟悉的卷积类似&#xff0c;unfold也是使用一个特定大小的窗口和步长自左至右、自上至下滑动&#xff0c;不同的是&#xff0c;卷积是滑动后与核求乘积&#xff08;所以取名为卷积&#xff09;&#…

Redis篇-2--原理篇1--I/O多路复用机制(5种I/O模型,I/O多路复用)

I/O多路复用机制&#xff1a; Redis 是通过I/O多路复用机制来管理大量客户端连接。这使得redis可以实现通过单线程来处理多个客户端连接的请求&#xff0c;避免了为每个客户端创建独立的线程&#xff0c;从而减少了上下文切换的开销&#xff0c;提高了系统的并发性和性能。 理解…

计算机毕设-基于springboot的某学院兼职平台的设计与实现(附源码+lw+ppt+开题报告)

博主介绍&#xff1a;✌多个项目实战经验、多个大型网购商城开发经验、在某机构指导学员上千名、专注于本行业领域✌ 技术范围&#xff1a;Java实战项目、Python实战项目、微信小程序/安卓实战项目、爬虫大数据实战项目、Nodejs实战项目、PHP实战项目、.NET实战项目、Golang实战…

Promise详解-1:初识Promise

最近在回顾ES6的知识&#xff0c;想整理下跟Promise相关的内容。我准备整一个Promise解读的系列&#xff0c;看看能深入到什么程度吧。由浅入深&#xff0c;先认识下Promise。 痛苦的回忆&#xff1a;回调地狱 假如现在让你维护一个“古老”的项目&#xff0c;缺少脚手架的加…

【蓝桥杯备战】Day 1

1.基础题目 LCR 018.验证回文串 给定一个字符串 s &#xff0c;验证 s 是否是 回文串 &#xff0c;只考虑字母和数字字符&#xff0c;可以忽略字母的大小写。 本题中&#xff0c;将空字符串定义为有效的 回文串 。 示例 1: 输入: s "A man, a plan, a canal: Panama…

让文案生成更具灵活性/chatGPT新功能canvas画布编辑

​ ​ OpenAI最近在2024年12月发布了canvas画布编辑功能&#xff0c;这是一项用途广泛的创新工具&#xff0c;专为需要高效创作文案的用户设计。 无论是职场人士、学生还是创作者&#xff0c;这项功能都能帮助快速生成、优化和编辑文案&#xff0c;提升效率的同时提高内容质量…

使用秘钥登录服务器

在我们测试或生产环境中&#xff0c;为了服务器安全性&#xff0c;有时可能需要以 SSH 密钥的方式登录服务器&#xff0c;接下来&#xff0c;将演示如何通过 SSH 私钥的方式来远程服务器。 一、远程服务器生成密钥对 1、首先在目标远程服务器下生成 SSH 密钥对 ssh-keygen然…

linux-16 关于shell(十五)date,clock,hwclock,man,时间管理,命令帮助

想显示一下当前系统上的时间该怎么显示&#xff1f;有一个命令叫做date&#xff0c;来看date命令&#xff0c;如下图&#xff0c; 第一个星期几对吧&#xff1f;然后是月日小时分钟秒&#xff0c;最后一个是年对吧&#xff1f;CST指的是它的时间格式&#xff0c;我这个可以先姑…

番外篇 | Hyper-YOLO:超图计算与YOLO架构相结合成为目标检测新的SOTA !

前言:Hello大家好,我是小哥谈。Hyper-YOLO,该方法融合了超图计算以捕捉视觉特征之间复杂的高阶关联。传统的YOLO模型虽然功能强大,但其颈部设计存在局限性,限制了跨层特征的融合以及高阶特征关系的利用。Hyper-YOLO在骨干和颈部的联合增强下,成为一个突破性的架构。在COC…

在 Ubuntu 中 make 是否是系统自带的?怎么样查看Linux系统中是否有make?

make 命令 并不是所有 Ubuntu 系统都默认安装的&#xff0c;但它通常是开发工具链的一部分&#xff0c;许多开发者会在安装系统后配置它。make 是一个非常重要的构建工具&#xff0c;用于自动化编译和构建过程&#xff0c;特别是在编译软件或内核时。 make 的来源 make 是一个…

ubuntu+ros新手笔记(一)

系统ubuntu20.04 ros noetic humble(源码安装失败&#xff0c;放弃源码安装了) 1. ubuntu安装vcs 拉取autoware源码的时候需要用到命令 vcs import src < autoware.ai.repos但是ubuntu默认没有安装vcs工具&#xff08;zsh: command not found: vcs&#xff09; 应使用以…

蛋白研究新热点:AI 全方位剖析 DHA 与 Ferrostatin - 1 的作用密码

胰腺癌是一种非常棘手的癌症&#xff0c;传统化疗药物往往对它收效甚微&#xff0c;很难提高患者的生存率。不过&#xff0c;研究人员发现了一种可能的新治疗方向 —— 利用双氢青蒿素&#xff08;DHA&#xff09;诱导癌细胞发生铁死亡。 下面将以Dihydroartemisinin induces …

大数据挖掘建模平台案例分享

大数据挖掘建模平台是由泰迪自主研发&#xff0c;面向企业级用户的大数据挖掘建模平台。平台采用可视化操作方式&#xff0c;通过丰富内置算法&#xff0c;帮助用户快速、一站式地进行数据分析及挖掘建模&#xff0c;可应用于处理海量数据、高复杂性的数据挖掘任务&#xff0c;…

docker安装、升级、以及sudo dockerd --debug查看启动失败的问题

1、docker安装包tar下载地址 Index of linux/static/stable/x86_64/ 2、下载tgz文件并解压 tar -zxvf docker-24.0.8.tgz 解压后docker文件夹下位docker相关文件 3、将老版本docker相关文件&#xff0c;备份 将 /usr/bin/docker下docker相关的文件&#xff0c;mv到备份目录…