KMP OpenHarmony 长度单位转换工具 - 毫米、厘米、米、千米、英寸、英尺、英里相互转换
本文介绍了一个基于Kotlin Multiplatform的跨端长度单位转换工具系统,支持公制(毫米、厘米、米、千米)和英制(英寸、英尺、码、英里)单位的相互转换。系统通过米作为中间单位实现精确转换,提供长度范围检查、描述分类和统计分析等功能。核心代码展示了公制、英制及跨系统转换的实现方式,采用标准化转换系数确保准确性。该工具适用于地图导航、工程计算等场景,通过KMP框架实现多平台共享同一套转换逻

目录
概述
本文档介绍如何在 Kotlin Multiplatform (KMP) 鸿蒙跨端开发中实现一个功能完整的长度单位转换工具系统。长度是物理学中的基本量,在日常生活、工程设计、地理测量等领域都有广泛应用。这个工具提供了对多种长度单位的全面转换支持,包括公制单位(毫米、厘米、米、千米)和英制单位(英寸、英尺、码、英里)等,以及长度转换的各种操作和分析。
在实际应用中,长度转换工具广泛应用于以下场景:地图应用、导航系统、建筑设计、工程计算、运动健身、国际贸易等。通过 KMP 框架的跨端能力,我们可以在不同平台上使用相同的长度转换逻辑,确保转换结果的准确性和一致性。
工具的特点
- 完整的长度单位支持:支持公制和英制单位的相互转换
- 精确的转换:使用标准的长度转换系数
- 双向转换:支持任意两种长度单位之间的转换
- 长度范围检查:检查长度值是否在合理范围内
- 长度分析:提供长度数据的详细分析
- 跨端兼容:一份 Kotlin 代码可同时服务多个平台
工具功能
1. 公制长度单位转换
公制长度单位是国际标准单位,基于 10 进制。毫米、厘米、米、千米是最常见的公制长度单位。公制长度转换需要处理小数点精度和单位之间的倍数关系。
- 毫米到厘米:1 cm = 10 mm
- 厘米到米:1 m = 100 cm
- 米到千米:1 km = 1000 m
- 跨单位转换:支持任意两个公制单位之间的转换
2. 英制长度单位转换
英制长度单位主要在美国和英国使用。英寸、英尺、码、英里是主要的英制长度单位。英制长度转换需要处理复杂的倍数关系。
- 英寸到英尺:1 ft = 12 in
- 英尺到码:1 yd = 3 ft
- 码到英里:1 mi = 1760 yd
- 跨单位转换:支持任意两个英制单位之间的转换
3. 公制与英制转换
公制和英制之间的转换需要使用标准的转换系数。这对于国际应用很重要。
- 英寸到厘米:1 in = 2.54 cm
- 英尺到米:1 ft = 0.3048 m
- 英里到千米:1 mi = 1.60934 km
- 精确转换:使用标准的国际转换系数
4. 长度范围检查
长度范围检查是验证长度值是否在合理范围内。不同的应用有不同的长度范围。长度范围检查对于数据质量控制很重要。
- 正数检查:长度必须为正数
- 合理范围检查:检查长度是否在常见范围内
- 单位验证:检查长度单位是否有效
- 错误报告:提供详细的错误信息
5. 长度描述和分类
长度描述是用自然语言描述长度的大小。长度分类是根据长度范围进行分类。长度描述和分类对于用户界面很有用。
- 长度等级:极小、很小、小、中等、大、很大、极大
- 距离描述:根据长度生成距离描述
- 应用场景:根据长度推荐应用场景
- 参考对象:提供长度的参考对象
6. 长度统计分析
长度统计分析是对长度数据进行统计和分析。长度统计分析对于工程计算和数据处理很有用。
- 最大长度:找出最大的长度
- 最小长度:找出最小的长度
- 平均长度:计算长度的平均值
- 长度分布:分析长度的分布
7. 长度转换历史
长度转换历史是记录之前的转换操作。长度转换历史对于用户查看和重复使用很有用。
- 转换记录:记录所有的转换操作
- 快速重复:快速重复之前的转换
- 历史查询:查询之前的转换结果
- 导出数据:导出转换历史
核心实现
1. 公制长度转换
fun millimeterToMeter(mm: Double): Double = mm / 1000
fun centimeterToMeter(cm: Double): Double = cm / 100
fun kilometerToMeter(km: Double): Double = km * 1000
fun meterToMillimeter(m: Double): Double = m * 1000
fun meterToCentimeter(m: Double): Double = m * 100
fun meterToKilometer(m: Double): Double = m / 1000
fun convertMetric(value: Double, fromUnit: String, toUnit: String): Double {
val meters = when (fromUnit.lowercase()) {
"mm" -> millimeterToMeter(value)
"cm" -> centimeterToMeter(value)
"m" -> value
"km" -> kilometerToMeter(value)
else -> 0.0
}
return when (toUnit.lowercase()) {
"mm" -> meterToMillimeter(meters)
"cm" -> meterToCentimeter(meters)
"m" -> meters
"km" -> meterToKilometer(meters)
else -> 0.0
}
}
代码说明: 公制长度转换通过米作为标准单位。先将源单位转换为米,再转换为目标单位。这种方法简洁且易于维护。
2. 英制长度转换
fun inchToFoot(inch: Double): Double = inch / 12
fun footToYard(foot: Double): Double = foot / 3
fun yardToMile(yard: Double): Double = yard / 1760
fun footToInch(foot: Double): Double = foot * 12
fun yardToFoot(yard: Double): Double = yard * 3
fun mileToYard(mile: Double): Double = mile * 1760
fun convertImperial(value: Double, fromUnit: String, toUnit: String): Double {
val feet = when (fromUnit.lowercase()) {
"in" -> inchToFoot(value)
"ft" -> value
"yd" -> yardToFoot(value)
"mi" -> mileToYard(value) * 3
else -> 0.0
}
return when (toUnit.lowercase()) {
"in" -> footToInch(feet)
"ft" -> feet
"yd" -> footToYard(feet)
"mi" -> feet / (1760 * 3)
else -> 0.0
}
}
代码说明: 英制长度转换通过英尺作为标准单位。先将源单位转换为英尺,再转换为目标单位。这种方法处理了英制单位复杂的倍数关系。
3. 公制与英制转换
fun inchToCentimeter(inch: Double): Double = inch * 2.54
fun centimeterToInch(cm: Double): Double = cm / 2.54
fun footToMeter(foot: Double): Double = foot * 0.3048
fun meterToFoot(m: Double): Double = m / 0.3048
fun mileToKilometer(mile: Double): Double = mile * 1.60934
fun kilometerToMile(km: Double): Double = km / 1.60934
fun convertBetweenSystems(value: Double, fromUnit: String, toUnit: String): Double {
val meters = when (fromUnit.lowercase()) {
"mm", "cm", "m", "km" -> convertMetric(value, fromUnit, "m")
"in" -> inchToMeter(value)
"ft" -> footToMeter(value)
"yd" -> yardToMeter(value)
"mi" -> mileToMeter(value)
else -> 0.0
}
return when (toUnit.lowercase()) {
"mm", "cm", "m", "km" -> convertMetric(meters, "m", toUnit)
"in" -> meterToInch(meters)
"ft" -> meterToFoot(meters)
"yd" -> meterToYard(meters)
"mi" -> meterToMile(meters)
else -> 0.0
}
}
代码说明: 公制与英制转换通过米作为中间单位。先将源单位转换为米,再转换为目标单位。这种方法统一了两个单位系统的转换。
4. 长度描述
fun describeLength(meters: Double): String {
return when {
meters < 0.001 -> "极小,微观级别"
meters < 0.01 -> "很小,毫米级别"
meters < 0.1 -> "小,厘米级别"
meters < 1 -> "中等,分米级别"
meters < 10 -> "大,米级别"
meters < 100 -> "很大,十米级别"
meters < 1000 -> "极大,百米级别"
else -> "超大,千米级别"
}
}
fun getLengthEmoji(meters: Double): String {
return when {
meters < 0.01 -> "🔬"
meters < 0.1 -> "📏"
meters < 1 -> "📐"
meters < 10 -> "🚪"
meters < 100 -> "🏠"
meters < 1000 -> "🏘️"
else -> "🌍"
}
}
代码说明: 长度描述根据米的范围提供自然语言描述。通过使用 emoji,可以提供更加直观的长度表示。
5. 长度统计分析
fun analyzeLengths(lengths: List<Double>, unit: String): Map<String, Any> {
if (lengths.isEmpty()) return mapOf("error" to "长度列表为空")
val stats = mutableMapOf<String, Any>()
stats["count"] = lengths.size
stats["max"] = lengths.maxOrNull() ?: 0.0
stats["min"] = lengths.minOrNull() ?: 0.0
stats["average"] = String.format("%.2f", lengths.average())
val sorted = lengths.sorted()
stats["median"] = if (lengths.size % 2 == 0) {
(sorted[lengths.size / 2 - 1] + sorted[lengths.size / 2]) / 2
} else {
sorted[lengths.size / 2]
}
stats["unit"] = unit
return stats
}
代码说明: 长度统计分析计算多个统计指标,包括最大值、最小值、平均值、中位数等。这对于分析长度数据很有用。
Kotlin 源代码
// LengthConverter.kt
class LengthConverter {
// 公制转换
fun millimeterToMeter(mm: Double): Double = mm / 1000
fun centimeterToMeter(cm: Double): Double = cm / 100
fun kilometerToMeter(km: Double): Double = km * 1000
fun meterToMillimeter(m: Double): Double = m * 1000
fun meterToCentimeter(m: Double): Double = m * 100
fun meterToKilometer(m: Double): Double = m / 1000
// 英制转换
fun inchToFoot(inch: Double): Double = inch / 12
fun footToYard(foot: Double): Double = foot / 3
fun yardToMile(yard: Double): Double = yard / 1760
fun footToInch(foot: Double): Double = foot * 12
fun yardToFoot(yard: Double): Double = yard * 3
fun mileToYard(mile: Double): Double = mile * 1760
// 公制与英制转换
fun inchToCentimeter(inch: Double): Double = inch * 2.54
fun centimeterToInch(cm: Double): Double = cm / 2.54
fun footToMeter(foot: Double): Double = foot * 0.3048
fun meterToFoot(m: Double): Double = m / 0.3048
fun mileToKilometer(mile: Double): Double = mile * 1.60934
fun kilometerToMile(km: Double): Double = km / 1.60934
fun inchToMeter(inch: Double): Double = inchToCentimeter(inch) / 100
fun meterToInch(m: Double): Double = centimeterToInch(m * 100)
fun yardToMeter(yard: Double): Double = footToMeter(yardToFoot(yard))
fun meterToYard(m: Double): Double = footToYard(meterToFoot(m))
fun mileToMeter(mile: Double): Double = kilometerToMeter(mileToKilometer(mile))
fun meterToMile(m: Double): Double = kilometerToMile(meterToKilometer(m))
fun convertMetric(value: Double, fromUnit: String, toUnit: String): Double {
val meters = when (fromUnit.lowercase()) {
"mm" -> millimeterToMeter(value)
"cm" -> centimeterToMeter(value)
"m" -> value
"km" -> kilometerToMeter(value)
else -> 0.0
}
return when (toUnit.lowercase()) {
"mm" -> meterToMillimeter(meters)
"cm" -> meterToCentimeter(meters)
"m" -> meters
"km" -> meterToKilometer(meters)
else -> 0.0
}
}
fun convertImperial(value: Double, fromUnit: String, toUnit: String): Double {
val feet = when (fromUnit.lowercase()) {
"in" -> inchToFoot(value)
"ft" -> value
"yd" -> yardToFoot(value)
"mi" -> mileToYard(value) * 3
else -> 0.0
}
return when (toUnit.lowercase()) {
"in" -> footToInch(feet)
"ft" -> feet
"yd" -> footToYard(feet)
"mi" -> feet / (1760 * 3)
else -> 0.0
}
}
fun convertBetweenSystems(value: Double, fromUnit: String, toUnit: String): Double {
val meters = when (fromUnit.lowercase()) {
"mm", "cm", "m", "km" -> convertMetric(value, fromUnit, "m")
"in" -> inchToMeter(value)
"ft" -> footToMeter(value)
"yd" -> yardToMeter(value)
"mi" -> mileToMeter(value)
else -> 0.0
}
return when (toUnit.lowercase()) {
"mm", "cm", "m", "km" -> convertMetric(meters, "m", toUnit)
"in" -> meterToInch(meters)
"ft" -> meterToFoot(meters)
"yd" -> meterToYard(meters)
"mi" -> meterToMile(meters)
else -> 0.0
}
}
fun validateLength(length: Double): Pair<Boolean, String> {
return if (length < 0) {
Pair(false, "长度不能为负数")
} else {
Pair(true, "长度有效")
}
}
fun describeLength(meters: Double): String {
return when {
meters < 0.001 -> "极小,微观级别"
meters < 0.01 -> "很小,毫米级别"
meters < 0.1 -> "小,厘米级别"
meters < 1 -> "中等,分米级别"
meters < 10 -> "大,米级别"
meters < 100 -> "很大,十米级别"
meters < 1000 -> "极大,百米级别"
else -> "超大,千米级别"
}
}
fun getLengthEmoji(meters: Double): String {
return when {
meters < 0.01 -> "🔬"
meters < 0.1 -> "📏"
meters < 1 -> "📐"
meters < 10 -> "🚪"
meters < 100 -> "🏠"
meters < 1000 -> "🏘️"
else -> "🌍"
}
}
fun analyzeLengths(lengths: List<Double>, unit: String): Map<String, Any> {
if (lengths.isEmpty()) return mapOf("error" to "长度列表为空")
val stats = mutableMapOf<String, Any>()
stats["count"] = lengths.size
stats["max"] = lengths.maxOrNull() ?: 0.0
stats["min"] = lengths.minOrNull() ?: 0.0
stats["average"] = String.format("%.2f", lengths.average())
val sorted = lengths.sorted()
stats["median"] = if (lengths.size % 2 == 0) {
(sorted[lengths.size / 2 - 1] + sorted[lengths.size / 2]) / 2
} else {
sorted[lengths.size / 2]
}
stats["unit"] = unit
return stats
}
fun formatLength(length: Double, unit: String, decimals: Int = 2): String {
return String.format("%.${decimals}f $unit", length)
}
fun getUnitInfo(unit: String): Map<String, String> {
return when (unit.lowercase()) {
"mm" -> mapOf("name" to "毫米", "system" to "公制", "symbol" to "mm")
"cm" -> mapOf("name" to "厘米", "system" to "公制", "symbol" to "cm")
"m" -> mapOf("name" to "米", "system" to "公制", "symbol" to "m")
"km" -> mapOf("name" to "千米", "system" to "公制", "symbol" to "km")
"in" -> mapOf("name" to "英寸", "system" to "英制", "symbol" to "in")
"ft" -> mapOf("name" to "英尺", "system" to "英制", "symbol" to "ft")
"yd" -> mapOf("name" to "码", "system" to "英制", "symbol" to "yd")
"mi" -> mapOf("name" to "英里", "system" to "英制", "symbol" to "mi")
else -> mapOf("error" to "不支持的长度单位")
}
}
}
fun main() {
val converter = LengthConverter()
println("=== 长度单位转换工具演示 ===\n")
// 公制转换
val cm = 100.0
println("$cm cm 转换:")
println(" 米: ${converter.convertMetric(cm, "cm", "m")} m")
println(" 毫米: ${converter.convertMetric(cm, "cm", "mm")} mm\n")
// 英制转换
val ft = 10.0
println("$ft ft 转换:")
println(" 英寸: ${converter.convertImperial(ft, "ft", "in")} in")
println(" 码: ${converter.convertImperial(ft, "ft", "yd")} yd\n")
// 公制与英制转换
println("100 cm 转英寸: ${converter.convertBetweenSystems(100.0, "cm", "in")} in")
println("10 ft 转米: ${converter.convertBetweenSystems(10.0, "ft", "m")} m\n")
// 长度描述
val meters = converter.convertMetric(100.0, "cm", "m")
println("${meters}m 的描述: ${converter.describeLength(meters)} ${converter.getLengthEmoji(meters)}")
}
Kotlin 代码说明: 这个实现提供了完整的长度转换功能。LengthConverter 类包含了公制转换、英制转换、系统间转换、验证、描述、分析等多个方法。通过使用标准的长度转换系数,确保了转换的准确性。
JavaScript 编译代码
// LengthConverter.js
class LengthConverter {
// 公制转换
millimeterToMeter(mm) { return mm / 1000; }
centimeterToMeter(cm) { return cm / 100; }
kilometerToMeter(km) { return km * 1000; }
meterToMillimeter(m) { return m * 1000; }
meterToCentimeter(m) { return m * 100; }
meterToKilometer(m) { return m / 1000; }
// 英制转换
inchToFoot(inch) { return inch / 12; }
footToYard(foot) { return foot / 3; }
yardToMile(yard) { return yard / 1760; }
footToInch(foot) { return foot * 12; }
yardToFoot(yard) { return yard * 3; }
mileToYard(mile) { return mile * 1760; }
// 公制与英制转换
inchToCentimeter(inch) { return inch * 2.54; }
centimeterToInch(cm) { return cm / 2.54; }
footToMeter(foot) { return foot * 0.3048; }
meterToFoot(m) { return m / 0.3048; }
mileToKilometer(mile) { return mile * 1.60934; }
kilometerToMile(km) { return km / 1.60934; }
inchToMeter(inch) { return this.inchToCentimeter(inch) / 100; }
meterToInch(m) { return this.centimeterToInch(m * 100); }
yardToMeter(yard) { return this.footToMeter(this.yardToFoot(yard)); }
meterToYard(m) { return this.footToYard(this.meterToFoot(m)); }
mileToMeter(mile) { return this.kilometerToMeter(this.mileToKilometer(mile)); }
meterToMile(m) { return this.kilometerToMile(this.meterToKilometer(m)); }
convertMetric(value, fromUnit, toUnit) {
let meters;
switch (fromUnit.toLowerCase()) {
case "mm": meters = this.millimeterToMeter(value); break;
case "cm": meters = this.centimeterToMeter(value); break;
case "m": meters = value; break;
case "km": meters = this.kilometerToMeter(value); break;
default: meters = 0;
}
switch (toUnit.toLowerCase()) {
case "mm": return this.meterToMillimeter(meters);
case "cm": return this.meterToCentimeter(meters);
case "m": return meters;
case "km": return this.meterToKilometer(meters);
default: return 0;
}
}
convertImperial(value, fromUnit, toUnit) {
let feet;
switch (fromUnit.toLowerCase()) {
case "in": feet = this.inchToFoot(value); break;
case "ft": feet = value; break;
case "yd": feet = this.yardToFoot(value); break;
case "mi": feet = this.mileToYard(value) * 3; break;
default: feet = 0;
}
switch (toUnit.toLowerCase()) {
case "in": return this.footToInch(feet);
case "ft": return feet;
case "yd": return this.footToYard(feet);
case "mi": return feet / (1760 * 3);
default: return 0;
}
}
convertBetweenSystems(value, fromUnit, toUnit) {
let meters;
switch (fromUnit.toLowerCase()) {
case "mm":
case "cm":
case "m":
case "km":
meters = this.convertMetric(value, fromUnit, "m");
break;
case "in": meters = this.inchToMeter(value); break;
case "ft": meters = this.footToMeter(value); break;
case "yd": meters = this.yardToMeter(value); break;
case "mi": meters = this.mileToMeter(value); break;
default: meters = 0;
}
switch (toUnit.toLowerCase()) {
case "mm":
case "cm":
case "m":
case "km":
return this.convertMetric(meters, "m", toUnit);
case "in": return this.meterToInch(meters);
case "ft": return this.meterToFoot(meters);
case "yd": return this.meterToYard(meters);
case "mi": return this.meterToMile(meters);
default: return 0;
}
}
validateLength(length) {
if (length < 0) {
return { valid: false, message: "长度不能为负数" };
}
return { valid: true, message: "长度有效" };
}
describeLength(meters) {
if (meters < 0.001) return "极小,微观级别";
if (meters < 0.01) return "很小,毫米级别";
if (meters < 0.1) return "小,厘米级别";
if (meters < 1) return "中等,分米级别";
if (meters < 10) return "大,米级别";
if (meters < 100) return "很大,十米级别";
if (meters < 1000) return "极大,百米级别";
return "超大,千米级别";
}
getLengthEmoji(meters) {
if (meters < 0.01) return "🔬";
if (meters < 0.1) return "📏";
if (meters < 1) return "📐";
if (meters < 10) return "🚪";
if (meters < 100) return "🏠";
if (meters < 1000) return "🏘️";
return "🌍";
}
analyzeLengths(lengths, unit) {
if (lengths.length === 0) return { error: "长度列表为空" };
const stats = {};
stats.count = lengths.length;
stats.max = Math.max(...lengths);
stats.min = Math.min(...lengths);
stats.average = (lengths.reduce((a, b) => a + b, 0) / lengths.length).toFixed(2);
const sorted = [...lengths].sort((a, b) => a - b);
stats.median = lengths.length % 2 === 0 ?
(sorted[lengths.length / 2 - 1] + sorted[lengths.length / 2]) / 2 :
sorted[Math.floor(lengths.length / 2)];
stats.unit = unit;
return stats;
}
formatLength(length, unit, decimals = 2) {
return length.toFixed(decimals) + " " + unit;
}
getUnitInfo(unit) {
switch (unit.toLowerCase()) {
case "mm": return { name: "毫米", system: "公制", symbol: "mm" };
case "cm": return { name: "厘米", system: "公制", symbol: "cm" };
case "m": return { name: "米", system: "公制", symbol: "m" };
case "km": return { name: "千米", system: "公制", symbol: "km" };
case "in": return { name: "英寸", system: "英制", symbol: "in" };
case "ft": return { name: "英尺", system: "英制", symbol: "ft" };
case "yd": return { name: "码", system: "英制", symbol: "yd" };
case "mi": return { name: "英里", system: "英制", symbol: "mi" };
default: return { error: "不支持的长度单位" };
}
}
}
// 使用示例
const converter = new LengthConverter();
console.log("=== 长度单位转换工具演示 ===\n");
const cm = 100;
console.log(`${cm} cm 转换:`);
console.log(" 米:", converter.convertMetric(cm, "cm", "m"), "m");
console.log(" 毫米:", converter.convertMetric(cm, "cm", "mm"), "mm");
const ft = 10;
console.log(`\n${ft} ft 转换:`);
console.log(" 英寸:", converter.convertImperial(ft, "ft", "in"), "in");
console.log(" 码:", converter.convertImperial(ft, "ft", "yd"), "yd");
console.log("\n100 cm 转英寸:", converter.convertBetweenSystems(100, "cm", "in"), "in");
console.log("10 ft 转米:", converter.convertBetweenSystems(10, "ft", "m"), "m");
const meters = converter.convertMetric(100, "cm", "m");
console.log(`\n${meters}m 的描述: ${converter.describeLength(meters)} ${converter.getLengthEmoji(meters)}`);
JavaScript 代码说明: JavaScript 版本是 Kotlin 代码的直接转译。由于 JavaScript 和 Kotlin 在语法上有差异,我们使用 switch 语句替代 when 表达式。整体逻辑和算法与 Kotlin 版本保持一致。
ArkTS 调用代码
// LengthConverterPage.ets
import { LengthConverter } from './LengthConverter';
@Entry
@Component
struct LengthConverterPage {
@State inputValue: string = '100';
@State fromUnit: string = 'cm';
@State toUnit: string = 'in';
@State result: string = '';
@State showResult: boolean = false;
@State isLoading: boolean = false;
@State operationType: string = 'convert';
private converter: LengthConverter = new LengthConverter();
private unitOptions = [
{ label: '毫米 (mm)', value: 'mm' },
{ label: '厘米 (cm)', value: 'cm' },
{ label: '米 (m)', value: 'm' },
{ label: '千米 (km)', value: 'km' },
{ label: '英寸 (in)', value: 'in' },
{ label: '英尺 (ft)', value: 'ft' },
{ label: '码 (yd)', value: 'yd' },
{ label: '英里 (mi)', value: 'mi' }
];
private operationOptions = [
{ label: '长度转换', value: 'convert' },
{ label: '长度验证', value: 'validate' },
{ label: '长度描述', value: 'describe' },
{ label: '单位信息', value: 'info' }
];
performOperation() {
this.isLoading = true;
try {
let resultText = '';
const length = parseFloat(this.inputValue);
switch (this.operationType) {
case 'convert':
const convertResult = this.converter.convertBetweenSystems(length, this.fromUnit, this.toUnit);
resultText = `${length} ${this.fromUnit} = ${convertResult.toFixed(4)} ${this.toUnit}`;
break;
case 'validate':
const validation = this.converter.validateLength(length);
resultText = validation.valid ? '✓ ' + validation.message : '✗ ' + validation.message;
break;
case 'describe':
let meters = length;
if (this.fromUnit !== 'm') {
meters = this.converter.convertBetweenSystems(length, this.fromUnit, 'm');
}
const description = this.converter.describeLength(meters);
const emoji = this.converter.getLengthEmoji(meters);
resultText = `${emoji} ${description}`;
break;
case 'info':
const info = this.converter.getUnitInfo(this.fromUnit);
resultText = `📊 ${info.name} 信息\n`;
resultText += `━━━━━━━━━━━━━━━━━━━━━\n`;
resultText += `符号: ${info.symbol}\n`;
resultText += `系统: ${info.system}`;
break;
default:
resultText = '未知操作';
}
this.result = resultText;
this.showResult = true;
} catch (error) {
this.result = '操作失败: ' + (error instanceof Error ? error.message : String(error));
this.showResult = true;
} finally {
this.isLoading = false;
}
}
build() {
Column() {
// 标题
Text('长度单位转换工具')
.fontSize(28)
.fontWeight(FontWeight.Bold)
.margin({ top: 20, bottom: 20 })
.textAlign(TextAlign.Center)
.width('100%')
// 操作类型选择
Column() {
Text('操作类型')
.fontSize(14)
.fontColor('#666666')
.margin({ bottom: 10 })
Select(this.operationOptions)
.value(this.operationType)
.onSelect((index: number, value?: string) => {
this.operationType = value || 'convert';
})
.width('100%')
.height(40)
}
.width('100%')
.padding(15)
.backgroundColor('#ffffff')
.borderRadius(10)
.border({ width: 1, color: '#eeeeee' })
.margin({ bottom: 20 })
// 长度单位选择
Row() {
Column() {
Text('源单位')
.fontSize(12)
.fontColor('#666666')
.margin({ bottom: 8 })
Select(this.unitOptions)
.value(this.fromUnit)
.onSelect((index: number, value?: string) => {
this.fromUnit = value || 'cm';
})
.width('100%')
.height(40)
}
.width('48%')
Text('→')
.fontSize(20)
.fontWeight(FontWeight.Bold)
.width('4%')
.textAlign(TextAlign.Center)
Column() {
Text('目标单位')
.fontSize(12)
.fontColor('#666666')
.margin({ bottom: 8 })
Select(this.unitOptions)
.value(this.toUnit)
.onSelect((index: number, value?: string) => {
this.toUnit = value || 'in';
})
.width('100%')
.height(40)
}
.width('48%')
}
.width('100%')
.padding(15)
.backgroundColor('#ffffff')
.borderRadius(10)
.border({ width: 1, color: '#eeeeee' })
.margin({ bottom: 20 })
// 输入框
Column() {
Text('输入长度值')
.fontSize(14)
.fontColor('#666666')
.margin({ bottom: 10 })
TextInput({ placeholder: '输入长度值' })
.value(this.inputValue)
.onChange((value: string) => {
this.inputValue = value;
})
.width('100%')
.height(45)
.padding({ left: 10, right: 10 })
.border({ width: 1, color: '#cccccc', radius: 8 })
.fontSize(14)
}
.width('100%')
.padding(15)
.backgroundColor('#ffffff')
.borderRadius(10)
.border({ width: 1, color: '#eeeeee' })
.margin({ bottom: 20 })
// 操作按钮
Button('执行操作')
.width('100%')
.height(45)
.fontSize(16)
.fontWeight(FontWeight.Bold)
.backgroundColor('#1B7837')
.fontColor('#ffffff')
.onClick(() => {
this.performOperation();
})
.margin({ bottom: 20 })
// 结果显示
if (this.showResult) {
Column() {
Text('结果')
.fontSize(16)
.fontWeight(FontWeight.Bold)
.fontColor('#FFFFFF')
.width('100%')
.padding(12)
.backgroundColor('#1B7837')
.borderRadius(8)
.margin({ bottom: 12 })
Scroll() {
Text(this.result)
.fontSize(14)
.fontColor('#333333')
.width('100%')
.padding(12)
.backgroundColor('#f9f9f9')
.borderRadius(6)
.textAlign(TextAlign.Start)
.selectable(true)
}
.width('100%')
.height(120)
}
.width('100%')
.padding(15)
.backgroundColor('#ffffff')
.borderRadius(10)
.border({ width: 1, color: '#eeeeee' })
}
Blank()
}
.width('100%')
.height('100%')
.padding(15)
.backgroundColor('#f5f5f5')
.scrollable(ScrollDirection.Vertical)
}
}
ArkTS 代码说明: ArkTS 调用代码展示了如何在 OpenHarmony 应用中使用长度转换工具。页面包含操作类型选择、源单位和目标单位选择、输入框、操作按钮和结果显示等功能。通过 @State 装饰器管理状态,实现了完整的用户交互流程。用户可以选择操作类型和长度单位,输入长度值,然后点击执行按钮获得结果。
实战案例
案例1:地图应用
在地图应用中,需要根据用户所在地区显示不同的距离单位。
fun displayDistance(meters: Double, region: String): Map<String, String> {
val converter = LengthConverter()
return when (region) {
"US" -> mapOf(
"distance" to converter.formatLength(converter.meterToFoot(meters), "ft"),
"description" to converter.describeLength(meters),
"emoji" to converter.getLengthEmoji(meters)
)
"UK" -> mapOf(
"distance" to converter.formatLength(converter.meterToMile(meters), "mi"),
"description" to converter.describeLength(meters),
"emoji" to converter.getLengthEmoji(meters)
)
else -> mapOf(
"distance" to converter.formatLength(meters, "m"),
"description" to converter.describeLength(meters),
"emoji" to converter.getLengthEmoji(meters)
)
}
}
案例2:建筑设计
在建筑设计中,需要将设计尺寸从公制转换为英制。
fun convertBlueprintDimensions(millimeters: Double): Map<String, String> {
val converter = LengthConverter()
val inches = converter.convertBetweenSystems(millimeters, "mm", "in")
val feet = converter.convertBetweenSystems(millimeters, "mm", "ft")
return mapOf(
"millimeters" to converter.formatLength(millimeters, "mm"),
"inches" to converter.formatLength(inches, "in"),
"feet" to converter.formatLength(feet, "ft"),
"description" to converter.describeLength(converter.convertMetric(millimeters, "mm", "m"))
)
}
案例3:运动健身
在运动健身应用中,需要记录和转换运动距离。
fun trackRunningDistance(kilometers: Double): Map<String, Any> {
val converter = LengthConverter()
val miles = converter.convertBetweenSystems(kilometers, "km", "mi")
val meters = converter.convertMetric(kilometers, "km", "m")
return mapOf(
"kilometers" to kilometers,
"miles" to miles,
"meters" to meters,
"description" to converter.describeLength(meters),
"emoji" to converter.getLengthEmoji(meters)
)
}
最佳实践
1. 单位验证
始终验证长度值是否为正数。长度不能为负数。
2. 精度管理
根据应用需求选择合适的精度。建筑应用需要更高的精度。
3. 单位明确
始终明确显示长度单位,避免用户混淆。
4. 系统一致
在同一应用中保持长度单位的一致性。
5. 用户体验
提供长度描述和 emoji,提高用户体验。
6. 错误处理
提供清晰的错误消息,帮助用户理解问题。
总结
长度单位转换工具是现代应用开发中的重要组件。通过 KMP 框架,我们可以创建一个跨端的长度转换系统,在 Kotlin、JavaScript 和 ArkTS 中使用相同的转换逻辑。这不仅提高了代码的可维护性,还确保了不同平台上转换结果的一致性。
在实际应用中,合理使用长度转换工具可以提高应用的国际化程度和用户体验。无论是地图应用、建筑设计还是运动健身,长度转换工具都能发挥重要作用。通过提供完整的长度转换功能和人性化的长度描述,我们可以帮助用户更好地理解和使用长度数据。
更多推荐


所有评论(0)