【引言】

温度是日常生活中常见的物理量,但不同国家和地区可能使用不同的温度单位,如摄氏度(Celsius)、华氏度(Fahrenheit)、开尔文(Kelvin)、兰氏度(Rankine)和列氏度(Reaumur)。为了方便用户在这些温度单位之间进行快速准确的转换,我们开发了一款温度转换工具。该工具支持五种温度单位之间的相互转换,旨在为用户提供便捷的服务。

【环境准备】

• 操作系统:Windows 10

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

• 目标设备:华为Mate60 Pro

• 开发语言:ArkTS

• 框架:ArkUI

• API版本:API 12

• 三方库:@nutpi/temperature-converter(核心算法)

【项目结构】

项目的核心组件是 TemperatureConverterApp,它负责构建整个应用的用户界面,并处理用户输入及温度单位之间的转换逻辑。

1. 温度单位类定义

我们定义了一个温度单位类 TemperatureUnit,用于封装温度单位的基本信息及其操作方法。每个温度单位都有一个标题、当前温度值和输入框的焦点状态。通过 setValue 方法,可以设置温度值并保留三位小数。

2. 温度单位类型枚举

为了更好地管理和使用温度单位,我们定义了一个温度单位类型对象 TemperatureUnitType,列出了五种温度单位的名称。

3. 应用程序主组件

TemperatureConverterApp 组件是整个应用的入口,它定义了应用的样式属性,并实现了UI的构建逻辑。组件中包含了多个状态变量,用于设置应用的颜色、字体大小等样式。

在UI构建逻辑中,我们使用了鸿蒙NEXT提供的布局组件,如 Column 和 Row,来组织页面的布局。页面顶部有一个标题 "温度转换",下方是一个垂直布局的容器,动态生成每个温度单位的输入框。每个输入框都绑定了 onChange 事件,当用户输入或更改温度值时,会触发相应的转换逻辑,更新其他温度单位的值。

4. 温度转换逻辑

温度转换逻辑通过调用 @nutpi/temperature-converter 库中的方法实现。当用户在某个温度单位的输入框中输入温度后,程序会根据当前输入的温度单位,调用相应的转换方法,计算出其他温度单位对应的值,并更新界面上的显示。

例如,如果用户在摄氏度输入框中输入温度,程序会自动计算出华氏度、开尔文、兰氏度和列氏度的值,并更新相应的输入框。

【用户体验】

为了提升用户体验,我们在输入框上添加了焦点状态的处理。当输入框获得焦点时,背景颜色和边框颜色会发生变化,以提示用户当前的操作位置。此外,输入框还支持输入过滤,只允许输入数字和小数点,确保输入的有效性。

【完整代码】

导包

ohpm install @nutpi/temperature-converter

代码

// 引入温度转换器模块
import { TemperatureConverter } from "@nutpi/temperature-converter" // 定义温度单位类型对象,用于存储各温度单位的名称
const TemperatureUnitType: object = Object({
Celsius: '摄氏度', // 摄氏度
Fahrenheit: '华氏度', // 华氏度
Kelvin: '开尔文', // 开尔文
Rankine: '兰氏度', // 兰氏度
Reaumur: '列氏度' // 列氏度
}) // 使用装饰器定义一个温度单位类
@ObservedV2
class TemperatureUnit {
title: string // 温度单位的标题
@Trace value: string = "" // 当前温度值,使用@Trace装饰器追踪变化
@Trace isInputFocused: boolean = false // 输入框是否获得焦点,同样使用@Trace追踪变化 // 构造函数,初始化时传入温度单位的标题
constructor(title: string) {
this.title = title
} // 设置温度值的方法,保留三位小数
setValue(value: number) {
this.value = `${parseFloat(value.toFixed(3))}` // 将数值转换成字符串,保留三位小数
console.info(`温度值:${this.value}`) // 打印当前温度值到控制台
}
} // 定义温度转换器应用程序的入口组件
@Entry
@Component
struct TemperatureConverterApp {
// 定义一系列的状态变量,用于设置应用的颜色、字体大小等样式
@State private primaryColor: string = "#080808" // 主色调
@State private secondaryColor: string = "#f7f7f7" // 次要色调
@State private bgColor: string = "#f4f8fb" // 背景颜色
@State private placeholderColor: string = "#2f9b6c" // 占位符颜色
@State private textColor: string = "#a3a3a3" // 文本颜色
@State private fontSizeSmall: number = 16 // 较小的字体大小
@State private fontSizeLarge: number = 18 // 较大的字体大小
@State private basePadding: number = 30 // 基础内边距 // 初始化温度单位数组,创建每个温度单位的实例
@State private temperatureUnits: TemperatureUnit[] =
Object.keys(TemperatureUnitType).map(unit => new TemperatureUnit(TemperatureUnitType[unit])) // 构建应用程序的UI
build() {
Column() { // 创建一个垂直布局容器
// 添加标题
Text('温度转换')
.fontColor(this.primaryColor) // 设置字体颜色
.fontSize(this.fontSizeSmall) // 设置字体大小
.width('100%') // 设置宽度
.height(50) // 设置高度
.textAlign(TextAlign.Center) // 设置文本对齐方式
.backgroundColor(Color.White) // 设置背景颜色
.shadow({ // 添加阴影效果
radius: 2, // 阴影半径
color: this.secondaryColor, // 阴影颜色
offsetX: 0, // X轴偏移量
offsetY: 5 // Y轴偏移量
}); // 循环遍历温度单位数组,动态生成每个温度单位的输入框
Column() {
ForEach(this.temperatureUnits, (unit: TemperatureUnit, index: number) => {
Row() { // 创建一个水平布局容器
// 显示温度单位的标题
Text(`${unit.title}`).fontSize(this.fontSizeSmall).fontColor(this.primaryColor) // 创建输入框
Row() {
TextInput({
text: unit.value, // 输入框的初始值
placeholder: !unit.isInputFocused ? `请输入${unit.title}` : '' // 输入框的占位符文本
})
.inputFilter('[0-9.-]', (e) => console.log(JSON.stringify(e))) // 过滤输入内容,只允许数字和小数点
.fontSize(this.fontSizeSmall) // 设置字体大小
.backgroundColor(Color.Transparent) // 设置背景颜色
.padding(0) // 设置内边距
.width('100%') // 设置宽度
.height('100%') // 设置高度
.placeholderColor(unit.isInputFocused ? this.placeholderColor : this.textColor) // 设置占位符颜色
.fontColor(unit.isInputFocused ? this.placeholderColor : this.primaryColor) // 设置字体颜色
.caretColor(this.placeholderColor) // 设置光标颜色
.borderRadius(0) // 设置圆角
.onBlur(() => unit.isInputFocused = false) // 失去焦点时的处理
.onFocus(() => unit.isInputFocused = true) // 获得焦点时的处理
.onChange((value: string) => { // 输入内容改变时的处理
if (!unit.isInputFocused) { // 如果输入框未获得焦点,则不处理数据
console.info(`当前位置${index}没有焦点,不处理数据内容`)
return
}
if (unit.value == value) { // 如果新旧值相同,则不处理
console.info(`当前位置${index}内容与修改内容相同,不需要继续处理`)
return
}
console.info(`onChange, unit.value:${unit.value}, value:${value}`) // 打印变更信息
const tempValue = Number(value); // 将输入的字符串转换成数字
unit.setValue(tempValue) // 更新当前温度单位的值 // 根据用户输入的温度单位,计算并更新其他温度单位的值
switch (index) {
case 0:
this.temperatureUnits[1].setValue(TemperatureConverter.celsiusToFahrenheit(tempValue))
this.temperatureUnits[2].setValue(TemperatureConverter.celsiusToKelvin(tempValue))
this.temperatureUnits[3].setValue(TemperatureConverter.celsiusToRankine(tempValue))
this.temperatureUnits[4].setValue(TemperatureConverter.celsiusToReaumur(tempValue))
break;
case 1:
this.temperatureUnits[0].setValue(TemperatureConverter.fahrenheitToCelsius(tempValue))
this.temperatureUnits[2].setValue(TemperatureConverter.fahrenheitToKelvin(tempValue))
this.temperatureUnits[3].setValue(TemperatureConverter.fahrenheitToRankine(tempValue))
this.temperatureUnits[4].setValue(TemperatureConverter.fahrenheitToReaumur(tempValue))
break;
case 2:
this.temperatureUnits[0].setValue(TemperatureConverter.kelvinToCelsius(tempValue))
this.temperatureUnits[1].setValue(TemperatureConverter.kelvinToFahrenheit(tempValue))
this.temperatureUnits[3].setValue(TemperatureConverter.kelvinToRankine(tempValue))
this.temperatureUnits[4].setValue(TemperatureConverter.kelvinToReaumur(tempValue))
break;
case 3:
this.temperatureUnits[0].setValue(TemperatureConverter.rankineToCelsius(tempValue))
this.temperatureUnits[1].setValue(TemperatureConverter.rankineToFahrenheit(tempValue))
this.temperatureUnits[2].setValue(TemperatureConverter.rankineToKelvin(tempValue))
this.temperatureUnits[4].setValue(TemperatureConverter.rankineToReaumur(tempValue))
break;
case 4:
this.temperatureUnits[0].setValue(TemperatureConverter.reaumurToCelsius(tempValue))
this.temperatureUnits[1].setValue(TemperatureConverter.reaumurToFahrenheit(tempValue))
this.temperatureUnits[2].setValue(TemperatureConverter.reaumurToKelvin(tempValue))
this.temperatureUnits[3].setValue(TemperatureConverter.reaumurToRankine(tempValue))
break;
}
});
}
.padding(`${this.basePadding / 2}lpx`) // 设置内边距
.backgroundColor(unit.isInputFocused ? this.bgColor : Color.Transparent) // 设置背景颜色
.layoutWeight(1) // 设置布局权重
.height(40) // 设置高度
.borderWidth(1) // 设置边框宽度
.borderRadius(10) // 设置圆角
.borderColor(unit.isInputFocused ? this.placeholderColor : this.secondaryColor) // 设置边框颜色
.margin({ left: `${this.basePadding / 2}lpx`, right: `${this.basePadding / 2}lpx` }); // 设置外边距
}.margin({ top: `${this.basePadding / 2}lpx`, bottom: `${this.basePadding / 2}lpx` }); // 设置外边距
})
}
.alignItems(HorizontalAlign.Start) // 设置水平对齐方式
.width('650lpx') // 设置宽度
.padding(`${this.basePadding}lpx`) // 设置内边距
.margin({ top: `${this.basePadding}lpx` }) // 设置外边距
.borderRadius(10) // 设置圆角
.backgroundColor(Color.White) // 设置背景颜色
.shadow({ // 添加阴影效果
radius: 10, // 阴影半径
color: this.secondaryColor, // 阴影颜色
offsetX: 0, // X轴偏移量
offsetY: 0 // Y轴偏移量
}); // 添加工具介绍部分
Column() {
// 添加标题
Text('工具介绍').fontSize(this.fontSizeLarge).fontWeight(600).fontColor(this.primaryColor); // 添加工具介绍的文本
Text('这款温度单位转换工具专为满足您在科学研究、日常生活及工作中的需求而设计。借助此工具,您可以轻松实现摄氏度(Celsius)、华氏度(Fahrenheit)和开尔文(Kelvin)之间的无缝切换。无论是学术研究、日常应用还是专业工作,都能为您提供精准便捷的温度换算服务。')
.textAlign(TextAlign.JUSTIFY) // 设置文本对齐方式
.fontSize(this.fontSizeSmall) // 设置字体大小
.fontColor(this.primaryColor) // 设置字体颜色
.margin({ top: `${this.basePadding / 2}lpx` }); // 设置外边距
}
.alignItems(HorizontalAlign.Start) // 设置水平对齐方式
.width('650lpx') // 设置宽度
.padding(`${this.basePadding}lpx`) // 设置内边距
.margin({ top: `${this.basePadding}lpx` }) // 设置外边距
.borderRadius(10) // 设置圆角
.backgroundColor(Color.White) // 设置背景颜色
.shadow({ // 添加阴影效果
radius: 10, // 阴影半径
color: this.secondaryColor, // 阴影颜色
offsetX: 0, // X轴偏移量
offsetY: 0 // Y轴偏移量
});
}
.height('100%') // 设置高度
.width('100%') // 设置宽度
.backgroundColor(this.bgColor); // 设置背景颜色
}
}

  

鸿蒙NEXT开发案例:温度转换的更多相关文章

  1. 最全华为鸿蒙 HarmonyOS 开发资料汇总

    开发 本示例基于 OpenHarmony 下的 JavaScript UI 框架,进行项目目录解读,JS FA.常用和自定义组件.用户交互.JS 动画的实现,通过本示例可以基本了解和学习到 JavaS ...

  2. 【推荐】使用Jquery+EasyUI进行框架项目开发案例讲解之一---员工管理源码分享

    使用Jquery+EasyUI 进行框架项目开发案例讲解之一 员工管理源码分享   在开始讲解之前,我们先来看一下什么是Jquery EasyUI?jQuery EasyUI是一组基于jQuery的U ...

  3. 使用Jquery+EasyUI进行框架项目开发案例解说之中的一个---员工管理源代码分享

    使用Jquery+EasyUI 进行框架项目开发案例解说之中的一个 员工管理源代码分享 在開始解说之前,我们先来看一下什么是Jquery EasyUI?jQuery EasyUI是一组基于jQuery ...

  4. 使用Jquery+EasyUI进行框架项目开发案例讲解之一---员工管理源码分享

    使用Jquery+EasyUI进行框架项目开发案例讲解之一---员工管理源码分享 使用Jquery+EasyUI 进行框架项目开发案例讲解之一 员工管理源码分享    在开始讲解之前,我们先来看一下什 ...

  5. FocusBI: SSIS 开发案例(原创)

    关注微信公众号:FocusBI 查看更多文章:加QQ群:808774277 获取学习资料和一起探讨问题. <商业智能教程>pdf下载地址 链接:https://pan.baidu.com/ ...

  6. 《实战突击:PHP项目开发案例整合(第2版)(含DVD光盘1张)》

    <实战突击:PHP项目开发案例整合(第2版)(含DVD光盘1张)> 基本信息 作者: 徐康明    辛洪郁 出版社:电子工业出版社 ISBN:9787121221378 上架时间:2014 ...

  7. (转)使用Jquery+EasyUI进行框架项目开发案例讲解之一---员工管理源码分享

    原文地址:http://www.cnblogs.com/huyong/archive/2013/09/24/3334848.html 使用Jquery+EasyUI 进行框架项目开发案例讲解之一 员工 ...

  8. 使用Jquery+EasyUI 进行框架项目开发案例讲解之五 模块(菜单)管理源码分享

    http://www.cnblogs.com/huyong/p/3454012.html 使用Jquery+EasyUI 进行框架项目开发案例讲解之五  模块(菜单)管理源码分享    在上四篇文章 ...

  9. 使用Jquery+EasyUI 进行框架项目开发案例讲解之四 组织机构管理源码分享

    http://www.cnblogs.com/huyong/p/3404647.html 在上三篇文章  <使用Jquery+EasyUI进行框架项目开发案例讲解之一---员工管理源码分享> ...

  10. ytu 2029: C语言实验——温度转换(水题)

    2029: C语言实验——温度转换 Time Limit: 1 Sec  Memory Limit: 64 MBSubmit: 12  Solved: 10[Submit][Status][Web B ...

随机推荐

  1. 爬虫案例1-爬取图片的三种方式之一:DrissionPage篇(3)

    @ 目录 前言 DrissionPage介绍 实战 共勉 博客 前言 继requests篇和selenium篇,本文是爬取图片的最后一个案例,利用了python第三方库DrissionPage来自动化 ...

  2. canvas图片旋转扩展出原生JS实现移动端横竖屏手写签名示例

    前提知识 canvas是提供了各种各样的接口去控制画布,比如旋转rotate方法. 这里的旋转并不是真的把这个画布旋转了,例如ctx.rotate(90 * Math.PI / 180)顺时针旋转90 ...

  3. Asp.net Core – CSS Isolation

    前言 ASP.NET Core 6.0 Razor Pages 新功能, 我是用 webpack 做打包的, 所以这个对我没有什么帮助. 但是了解一下是可以的. 希望 .NET 会继续发展的更好, 多 ...

  4. Angular 学习笔记 (Typescript 高级篇)

    由于 typescript 越来越复杂. 所以特意开多一个篇幅来记入一些比较难的, 和一些到了一定程度需要知道的基础. 主要参考 https://basarat.gitbook.io/typescri ...

  5. 前端基本功——面试必问系列(1):都2024了,还没吃透Promise?一文搞懂

    写在前面: 大家好,我是山里看瓜,该系列文章是为了帮助大家不管面试还是开发对前端的一些基本但是很重要的知识点认识更加深入和全面. 想写这个系列文章的初衷是:我发现前端的很多基本知识,使用起来很简单,定 ...

  6. 学好QT框架之后可以做什么工作?QT技术框架现代化行业大型复杂应用的经典成功案例

    简介 本文粗略的介绍了QT框架的软件开发技术生态体系的全球影响力:QT框架在文字办公领域.CAD三维图形领域.Linux操作系统领域.物联网领域.汽车电子领域以及数字医疗领域等现代化行业的大型复杂应用 ...

  7. 即刻报名 | Flutter Engage China 线上见!

    在刚刚过去的 Flutter Engage 活动上,我们正式发布了 Flutter 2: 为任何平台创建美观.快速且可移植应用的能力得以更上一层楼.通过 Flutter 2,开发者可以使用相同的代码库 ...

  8. 【赵渝强老师】在MongoDB中使用MapReduce方式计算聚合

    MapReduce 能够计算非常复杂的聚合逻辑,非常灵活,但是,MapReduce非常慢,不应该用于实时的数据分析中.MapReduce能够在多台Server上并行执行,每台Server只负责完成一部 ...

  9. 分析ueventd Coldboot耗时问题

    安卓go平台启动时间发现如下ueventd耗时1.907s问题: 01-11 00:20:02.854 0 0 I init : Parsing file /odm/etc/init... 01-11 ...

  10. cf1632 Codeforces Round #769 (Div. 2)题解

    A ABC 水题0.0 B Roof Construction 构造题,经过实验构造出了0的右边是不超过\(n\)的最大的\(2^k\rightarrow n\),左边是\(2^k-1,2^k-2,. ...