在这里插入图片描述

目录

  1. 概述
  2. 工具功能
  3. 核心实现
  4. Kotlin 源代码
  5. JavaScript 编译代码
  6. ArkTS 调用代码
  7. 实战案例
  8. 最佳实践

概述

本文档介绍如何在 Kotlin Multiplatform (KMP) 鸿蒙跨端开发中实现一个完整的国际旅行单位转换工具。国际旅行涉及多种单位制的转换,包括身高、体重、温度、距离和体积等。这个案例展示了如何使用 Kotlin 的多条件判断和数学计算来创建一个功能丰富的旅行辅助工具。

国际旅行单位转换工具是旅行者的必备工具,它能够根据用户的需求,快速将一种单位制转换为另一种单位制。无论是美国的英制单位、欧洲的公制单位,还是其他国家的特殊单位,这个工具都能提供准确的转换结果。通过 KMP,这个工具可以无缝编译到 JavaScript,在 OpenHarmony 应用中运行,为旅行者提供便捷的单位转换服务。

工具的特点

  • 多类型转换:支持身高、体重、温度、距离、体积等多种类型的转换
  • 国际单位支持:支持英制、公制等多种国际单位制
  • 准确转换:采用国际标准的转换系数,确保转换的准确性
  • 旅行建议:根据转换结果提供旅行相关的建议
  • 易于使用:简单的输入格式,快速的转换速度
  • 跨端兼容:一份 Kotlin 代码可同时服务多个平台

工具功能

1. 身高转换

身高转换支持英尺(ft)、英寸(in)、米(m)和厘米(cm)等单位:

  • 英尺 (ft):美国和英国常用的身高单位,1 英尺 = 30.48 厘米
  • 英寸 (in):英制系统中的小单位,1 英寸 = 2.54 厘米
  • 米 (m):国际标准单位,1 米 = 100 厘米
  • 厘米 (cm):公制系统中的常用单位

系统会根据转换结果提供身高评估:

  • 身高 < 150 cm:身高较矮
  • 身高 150-170 cm:身高正常
  • 身高 170-190 cm:身高较高
  • 身高 ≥ 190 cm:身高非常高

2. 体重转换

体重转换支持磅(lb)、千克(kg)、盎司(oz)和英石(st)等单位:

  • 磅 (lb):美国和英国常用的体重单位,1 磅 = 0.453592 千克
  • 千克 (kg):国际标准单位,是公制系统中的基本单位
  • 盎司 (oz):英制系统中的小单位,1 盎司 = 0.0283495 千克
  • 英石 (st):英国常用的体重单位,1 英石 = 6.35029 千克

系统会根据转换结果提供体重评估:

  • 体重 < 50 kg:体重较轻
  • 体重 50-80 kg:体重正常
  • 体重 80-100 kg:体重偏重
  • 体重 ≥ 100 kg:体重较重

3. 温度转换

温度转换支持摄氏度(C)、华氏度(F)和开尔文(K)等单位:

  • 摄氏度 (°C):国际标准温度单位,水的冰点为 0°C,沸点为 100°C
  • 华氏度 (°F):美国常用的温度单位,水的冰点为 32°F,沸点为 212°F
  • 开尔文 (K):物理学中的绝对温度单位,绝对零度为 0K

系统会根据转换结果提供天气评估:

  • 温度 < 0°C:极冷
  • 温度 0-10°C:寒冷
  • 温度 10-20°C:凉爽
  • 温度 20-30°C:温暖
  • 温度 ≥ 30°C:炎热

4. 距离转换

距离转换支持英里(mi)、公里(km)、米(m)、英尺(ft)和码(yd)等单位:

  • 英里 (mi):美国和英国常用的距离单位,1 英里 = 1.60934 公里
  • 公里 (km):国际标准单位,1 公里 = 1000 米
  • 米 (m):公制系统中的基本单位
  • 英尺 (ft):英制系统中的常用单位,1 英尺 = 0.3048 米
  • 码 (yd):英制系统中的单位,1 码 = 0.9144 米

系统会根据不同国家提供旅行建议:

  • 美国使用英里 (mi)
  • 欧洲使用公里 (km)
  • 英国使用英里 (mi)

5. 体积转换

体积转换支持杯(cup)、毫升(ml)、升(l)、液体盎司(fl oz)等单位,特别适合烹饪和购物:

  • 杯 (cup):美国食谱中常用的单位,1 杯 = 236.588 毫升
  • 毫升 (ml):公制系统中的基本单位
  • 升 (l):公制系统中的常用单位,1 升 = 1000 毫升
  • 液体盎司 (fl oz):英制系统中的单位,1 液体盎司 = 29.5735 毫升
  • 汤匙 (tbsp):烹饪中常用的单位,1 汤匙 = 14.7868 毫升
  • 茶匙 (tsp):烹饪中常用的单位,1 茶匙 = 4.92892 毫升

系统会根据不同国家提供食谱建议:

  • 美国食谱使用杯 (cup)
  • 欧洲食谱使用毫升 (ml)
  • 英国食谱使用液体盎司 (fl oz)

核心实现

算法原理

国际旅行单位转换工具的核心算法包括:

  1. 输入解析:解析用户输入的转换类型、数值和单位
  2. 中间单位转换:将源单位转换为中间单位(如厘米、千克、摄氏度等)
  3. 目标单位转换:将中间单位转换为目标单位
  4. 结果格式化:将转换结果格式化为易读的格式
  5. 建议生成:根据转换结果生成相关的旅行或烹饪建议

转换系数

系统使用国际标准的转换系数:

身高转换系数:

  • 1 英尺 = 30.48 厘米
  • 1 英寸 = 2.54 厘米
  • 1 米 = 100 厘米

体重转换系数:

  • 1 磅 = 0.453592 千克
  • 1 盎司 = 0.0283495 千克
  • 1 英石 = 6.35029 千克

温度转换公式:

  • 摄氏度 → 华氏度:(°C × 9/5) + 32
  • 华氏度 → 摄氏度:(°F - 32) × 5/9
  • 摄氏度 → 开尔文:°C + 273.15

距离转换系数:

  • 1 英里 = 1.60934 公里
  • 1 英尺 = 0.3048 米
  • 1 码 = 0.9144 米

体积转换系数:

  • 1 杯 = 236.588 毫升
  • 1 汤匙 = 14.7868 毫升
  • 1 茶匙 = 4.92892 毫升
  • 1 液体盎司 = 29.5735 毫升

Kotlin 源代码

// 案例 34: 国际旅行单位转换工具
@OptIn(ExperimentalJsExport::class)
@JsExport
fun travelUnitConverter(inputData: String = "height 6 ft m"): String {
    if (inputData.isEmpty()) {
        return "❌ 错误: 输入不能为空\n请输入: 类型 数值 源单位 目标单位\n类型: height/weight/temperature/distance/volume"
    }
    
    val parts = inputData.trim().split(" ")
    if (parts.size != 4) {
        return "❌ 错误: 输入格式不正确\n请输入: 类型 数值 源单位 目标单位"
    }
    
    val type = parts[0].lowercase()
    val value = parts[1].toDoubleOrNull()
    val fromUnit = parts[2].lowercase()
    val toUnit = parts[3].lowercase()
    
    if (value == null) {
        return "❌ 错误: 数值输入无效"
    }
    
    if (value <= 0) {
        return "❌ 错误: 数值必须大于 0"
    }
    
    // 1. 身高转换 (ft, in, m, cm)
    if (type == "height") {
        val valueInCm = when (fromUnit) {
            "ft" -> value * 30.48
            "in" -> value * 2.54
            "m" -> value * 100
            "cm" -> value
            else -> return "❌ 错误: 不支持的身高单位 ($fromUnit)"
        }
        
        val result = when (toUnit) {
            "ft" -> valueInCm / 30.48
            "in" -> valueInCm / 2.54
            "m" -> valueInCm / 100
            "cm" -> valueInCm
            else -> return "❌ 错误: 不支持的身高单位 ($toUnit)"
        }
        
        val tips = when {
            result < 150 -> "⚠️ 身高较矮"
            result < 170 -> "✅ 身高正常"
            result < 190 -> "✅ 身高较高"
            else -> "⚠️ 身高非常高"
        }
        
        return "✈️ 国际旅行单位转换\n" +
               "━━━━━━━━━━━━━━━━━━━━━\n" +
               "📏 身高转换\n\n" +
               "输入: $value $fromUnit\n" +
               "输出: ${(result * 100).toInt() / 100.0} $toUnit\n\n" +
               "评估: $tips\n\n" +
               "转换说明:\n" +
               "• 1 英尺 (ft) = 30.48 厘米\n" +
               "• 1 英寸 (in) = 2.54 厘米\n" +
               "• 1 米 (m) = 100 厘米\n\n" +
               "━━━━━━━━━━━━━━━━━━━━━\n" +
               "✅ 转换完成!"
    }
    
    // 2. 体重转换 (lb, kg, oz)
    if (type == "weight") {
        val valueInKg = when (fromUnit) {
            "lb" -> value * 0.453592
            "kg" -> value
            "oz" -> value * 0.0283495
            "st" -> value * 6.35029
            else -> return "❌ 错误: 不支持的体重单位 ($fromUnit)"
        }
        
        val result = when (toUnit) {
            "lb" -> valueInKg / 0.453592
            "kg" -> valueInKg
            "oz" -> valueInKg / 0.0283495
            "st" -> valueInKg / 6.35029
            else -> return "❌ 错误: 不支持的体重单位 ($toUnit)"
        }
        
        val tips = when {
            result < 50 -> "⚠️ 体重较轻"
            result < 80 -> "✅ 体重正常"
            result < 100 -> "⚠️ 体重偏重"
            else -> "⚠️ 体重较重"
        }
        
        return "✈️ 国际旅行单位转换\n" +
               "━━━━━━━━━━━━━━━━━━━━━\n" +
               "⚖️ 体重转换\n\n" +
               "输入: $value $fromUnit\n" +
               "输出: ${(result * 100).toInt() / 100.0} $toUnit\n\n" +
               "评估: $tips\n\n" +
               "转换说明:\n" +
               "• 1 磅 (lb) = 0.453592 千克\n" +
               "• 1 盎司 (oz) = 0.0283495 千克\n" +
               "• 1 英石 (st) = 6.35029 千克\n\n" +
               "━━━━━━━━━━━━━━━━━━━━━\n" +
               "✅ 转换完成!"
    }
    
    // 3. 温度转换 (C, F, K)
    if (type == "temperature") {
        val valueInCelsius = when (fromUnit) {
            "c" -> value
            "f" -> (value - 32) * 5 / 9
            "k" -> value - 273.15
            else -> return "❌ 错误: 不支持的温度单位 ($fromUnit)"
        }
        
        val result = when (toUnit) {
            "c" -> valueInCelsius
            "f" -> valueInCelsius * 9 / 5 + 32
            "k" -> valueInCelsius + 273.15
            else -> return "❌ 错误: 不支持的温度单位 ($toUnit)"
        }
        
        val tips = when {
            result < 0 -> "❄️ 极冷"
            result < 10 -> "🧊 寒冷"
            result < 20 -> "🌤️ 凉爽"
            result < 30 -> "☀️ 温暖"
            else -> "🔥 炎热"
        }
        
        return "✈️ 国际旅行单位转换\n" +
               "━━━━━━━━━━━━━━━━━━━━━\n" +
               "🌡️ 温度转换\n\n" +
               "输入: $value °$fromUnit\n" +
               "输出: ${(result * 100).toInt() / 100.0} °$toUnit\n\n" +
               "天气评估: $tips\n\n" +
               "转换公式:\n" +
               "• 摄氏度 → 华氏度: (°C × 9/5) + 32\n" +
               "• 华氏度 → 摄氏度: (°F - 32) × 5/9\n" +
               "• 摄氏度 → 开尔文: °C + 273.15\n\n" +
               "━━━━━━━━━━━━━━━━━━━━━\n" +
               "✅ 转换完成!"
    }
    
    // 4. 距离转换 (mi, km, m, ft)
    if (type == "distance") {
        val valueInKm = when (fromUnit) {
            "mi" -> value * 1.60934
            "km" -> value
            "m" -> value / 1000
            "ft" -> value * 0.0003048
            "yd" -> value * 0.0009144
            else -> return "❌ 错误: 不支持的距离单位 ($fromUnit)"
        }
        
        val result = when (toUnit) {
            "mi" -> valueInKm / 1.60934
            "km" -> valueInKm
            "m" -> valueInKm * 1000
            "ft" -> valueInKm / 0.0003048
            "yd" -> valueInKm / 0.0009144
            else -> return "❌ 错误: 不支持的距离单位 ($toUnit)"
        }
        
        return "✈️ 国际旅行单位转换\n" +
               "━━━━━━━━━━━━━━━━━━━━━\n" +
               "🗺️ 距离转换\n\n" +
               "输入: $value $fromUnit\n" +
               "输出: ${(result * 100).toInt() / 100.0} $toUnit\n\n" +
               "转换说明:\n" +
               "• 1 英里 (mi) = 1.60934 公里\n" +
               "• 1 英尺 (ft) = 0.3048 米\n" +
               "• 1 码 (yd) = 0.9144 米\n\n" +
               "旅行建议:\n" +
               "• 美国使用英里 (mi)\n" +
               "• 欧洲使用公里 (km)\n" +
               "• 英国使用英里 (mi)\n\n" +
               "━━━━━━━━━━━━━━━━━━━━━\n" +
               "✅ 转换完成!"
    }
    
    // 5. 体积转换 (cup, ml, l, fl oz)
    if (type == "volume") {
        val valueInMl = when (fromUnit) {
            "cup" -> value * 236.588
            "ml" -> value
            "l" -> value * 1000
            "fl oz" -> value * 29.5735
            "tbsp" -> value * 14.7868
            "tsp" -> value * 4.92892
            else -> return "❌ 错误: 不支持的体积单位 ($fromUnit)"
        }
        
        val result = when (toUnit) {
            "cup" -> valueInMl / 236.588
            "ml" -> valueInMl
            "l" -> valueInMl / 1000
            "fl oz" -> valueInMl / 29.5735
            "tbsp" -> valueInMl / 14.7868
            "tsp" -> valueInMl / 4.92892
            else -> return "❌ 错误: 不支持的体积单位 ($toUnit)"
        }
        
        return "✈️ 国际旅行单位转换\n" +
               "━━━━━━━━━━━━━━━━━━━━━\n" +
               "🥤 体积转换\n\n" +
               "输入: $value $fromUnit\n" +
               "输出: ${(result * 100).toInt() / 100.0} $toUnit\n\n" +
               "烹饪参考:\n" +
               "• 1 杯 (cup) = 236.588 毫升\n" +
               "• 1 汤匙 (tbsp) = 14.7868 毫升\n" +
               "• 1 茶匙 (tsp) = 4.92892 毫升\n" +
               "• 1 液体盎司 (fl oz) = 29.5735 毫升\n\n" +
               "旅行建议:\n" +
               "• 美国食谱使用杯 (cup)\n" +
               "• 欧洲食谱使用毫升 (ml)\n" +
               "• 英国食谱使用液体盎司 (fl oz)\n\n" +
               "━━━━━━━━━━━━━━━━━━━━━\n" +
               "✅ 转换完成!"
    }
    
    return "❌ 错误: 不支持的转换类型 ($type)\n支持的类型: height, weight, temperature, distance, volume"
}

Kotlin 代码详解

这个 Kotlin 函数实现了一个完整的国际旅行单位转换工具。函数接收一个字符串参数,包含转换类型、数值、源单位和目标单位。

首先,函数进行严格的输入验证。它检查输入是否为空,是否包含正确数量的字段,以及数值是否有效。

然后,函数根据转换类型(身高、体重、温度、距离、体积)进行相应的转换。对于每种类型,函数都:

  1. 将源单位转换为中间单位(如厘米、千克、摄氏度等)
  2. 将中间单位转换为目标单位
  3. 根据转换结果提供相关的评估或建议

最后,函数返回一个格式化的结果字符串,包含转换结果、转换说明和旅行建议。


JavaScript 编译代码

// 编译后的 JavaScript 代码(部分示例)
function travelUnitConverter(inputData) {
    if (inputData === undefined) {
        inputData = "height 6 ft m";
    }
    
    if (inputData.length === 0) {
        return "❌ 错误: 输入不能为空\n请输入: 类型 数值 源单位 目标单位\n类型: height/weight/temperature/distance/volume";
    }
    
    var parts = inputData.trim().split(" ");
    if (parts.length !== 4) {
        return "❌ 错误: 输入格式不正确\n请输入: 类型 数值 源单位 目标单位";
    }
    
    var type = parts[0].toLowerCase();
    var value = parseFloat(parts[1]);
    var fromUnit = parts[2].toLowerCase();
    var toUnit = parts[3].toLowerCase();
    
    if (isNaN(value)) {
        return "❌ 错误: 数值输入无效";
    }
    
    if (value <= 0) {
        return "❌ 错误: 数值必须大于 0";
    }
    
    // 身高转换
    if (type === "height") {
        var valueInCm;
        switch (fromUnit) {
            case "ft": valueInCm = value * 30.48; break;
            case "in": valueInCm = value * 2.54; break;
            case "m": valueInCm = value * 100; break;
            case "cm": valueInCm = value; break;
            default: return "❌ 错误: 不支持的身高单位 (" + fromUnit + ")";
        }
        
        var result;
        switch (toUnit) {
            case "ft": result = valueInCm / 30.48; break;
            case "in": result = valueInCm / 2.54; break;
            case "m": result = valueInCm / 100; break;
            case "cm": result = valueInCm; break;
            default: return "❌ 错误: 不支持的身高单位 (" + toUnit + ")";
        }
        
        var tips;
        if (result < 150) {
            tips = "⚠️ 身高较矮";
        } else if (result < 170) {
            tips = "✅ 身高正常";
        } else if (result < 190) {
            tips = "✅ 身高较高";
        } else {
            tips = "⚠️ 身高非常高";
        }
        
        return "✈️ 国际旅行单位转换\n" +
               "━━━━━━━━━━━━━━━━━━━━━\n" +
               "📏 身高转换\n\n" +
               "输入: " + value + " " + fromUnit + "\n" +
               "输出: " + (Math.floor(result * 100) / 100) + " " + toUnit + "\n\n" +
               "评估: " + tips + "\n\n" +
               "转换说明:\n" +
               "• 1 英尺 (ft) = 30.48 厘米\n" +
               "• 1 英寸 (in) = 2.54 厘米\n" +
               "• 1 米 (m) = 100 厘米\n\n" +
               "━━━━━━━━━━━━━━━━━━━━━\n" +
               "✅ 转换完成!";
    }
    
    // 类似的体重、温度、距离、体积转换...
    
    return "❌ 错误: 不支持的转换类型 (" + type + ")\n支持的类型: height, weight, temperature, distance, volume";
}

JavaScript 代码详解

Kotlin 代码编译到 JavaScript 后,保留了原有的逻辑结构,但使用 JavaScript 的语法和 API。主要的转换包括:

  1. 类型转换:Kotlin 的 toDoubleOrNull() 转换为 JavaScript 的 parseFloat()
  2. 条件语句:Kotlin 的 when 表达式转换为 JavaScript 的 switchif-else
  3. 字符串处理:Kotlin 的字符串模板转换为 JavaScript 的字符串拼接
  4. 数学运算:保持相同的数学计算逻辑

ArkTS 调用代码

import { travelUnitConverter } from './hellokjs';

@Entry
@Component
struct Index {
  @State message: string = '准备就绪';
  @State conversionType: string = 'height';
  @State value: string = '6';
  @State fromUnit: string = 'ft';
  @State toUnit: string = 'm';
  @State resultText: string = '';
  @State isLoading: boolean = false;

  aboutToAppear(): void {
    this.generateNewCase();
  }

  generateNewCase(): void {
    this.resultText = '';
    this.message = '准备就绪';
    
    const samples = [
      { type: 'height', v: '6', from: 'ft', to: 'm' },
      { type: 'weight', v: '150', from: 'lb', to: 'kg' },
      { type: 'temperature', v: '98.6', from: 'f', to: 'c' },
      { type: 'distance', v: '100', from: 'mi', to: 'km' },
      { type: 'volume', v: '2', from: 'cup', to: 'ml' }
    ];
    
    const random = samples[Math.floor(Math.random() * samples.length)];
    this.conversionType = random.type;
    this.value = random.v;
    this.fromUnit = random.from;
    this.toUnit = random.to;
  }

  convert(): void {
    this.isLoading = true;
    try {
      const input: string = `${this.conversionType} ${this.value} ${this.fromUnit} ${this.toUnit}`;
      const result: string = travelUnitConverter(input);
      this.resultText = result;
      console.log(result);
      this.message = '✓ 转换完成';
    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : String(error);
      this.message = `✗ 错误: ${errorMessage}`;
    } finally {
      this.isLoading = false;
    }
  }

  build() {
    Column() {
      // ===== 顶部标题栏 - 旅行蓝色主题 =====
      Column() {
        Text('✈️ Travel Unit Converter')
          .fontSize(28)
          .fontWeight(FontWeight.Bold)
          .fontColor(Color.White)
          .margin({ bottom: 8 })
        
        Text('International Unit Conversion Tool')
          .fontSize(13)
          .fontColor('#B3E5FC')
      }
      .width('100%')
      .padding(24)
      .backgroundColor('#01579B')
      .alignItems(HorizontalAlign.Start)

      // ===== 主内容区域 =====
      Scroll() {
        Column() {
          // 输入卡片
          Column() {
            Row() {
              Text('🔄 Conversion')
                .fontSize(16)
                .fontWeight(FontWeight.Bold)
                .fontColor('#FFFFFF')
              
              Blank()
              
              Text('🎲 Random')
                .fontSize(12)
                .fontColor(Color.White)
                .padding({ left: 10, right: 10, top: 6, bottom: 6 })
                .backgroundColor('#004D7A')
                .borderRadius(12)
                .onClick(() => {
                  this.generateNewCase();
                })
            }
            .width('100%')
            .margin({ bottom: 18 })

            // 转换类型
            TextInput({ placeholder: 'Type (height/weight/temperature/distance/volume)', text: this.conversionType })
              .width('100%')
              .height(50)
              .padding(14)
              .fontSize(15)
              .fontColor('#000000')
              .placeholderColor('#999999')
              .border({ width: 2, color: '#01579B' })
              .borderRadius(12)
              .backgroundColor('#E1F5FE')
              .onChange((value: string) => {
                this.conversionType = value;
              })
              .margin({ bottom: 14 })

            // 数值输入
            TextInput({ placeholder: 'Value', text: this.value })
              .width('100%')
              .height(50)
              .padding(14)
              .fontSize(15)
              .fontColor('#000000')
              .placeholderColor('#999999')
              .border({ width: 2, color: '#01579B' })
              .borderRadius(12)
              .backgroundColor('#E1F5FE')
              .onChange((value: string) => {
                this.value = value;
              })
              .margin({ bottom: 14 })

            // 源单位
            TextInput({ placeholder: 'From Unit', text: this.fromUnit })
              .width('100%')
              .height(50)
              .padding(14)
              .fontSize(15)
              .fontColor('#000000')
              .placeholderColor('#999999')
              .border({ width: 2, color: '#01579B' })
              .borderRadius(12)
              .backgroundColor('#E1F5FE')
              .onChange((value: string) => {
                this.fromUnit = value;
              })
              .margin({ bottom: 14 })

            // 目标单位
            TextInput({ placeholder: 'To Unit', text: this.toUnit })
              .width('100%')
              .height(50)
              .padding(14)
              .fontSize(15)
              .fontColor('#000000')
              .placeholderColor('#999999')
              .border({ width: 2, color: '#01579B' })
              .borderRadius(12)
              .backgroundColor('#E1F5FE')
              .onChange((value: string) => {
                this.toUnit = value;
              })
              .margin({ bottom: 20 })

            // 转换按钮
            Button(this.isLoading ? 'Converting...' : 'Convert')
              .width('100%')
              .height(54)
              .fontSize(16)
              .fontWeight(FontWeight.Bold)
              .fontColor(Color.White)
              .backgroundColor(this.isLoading ? '#004D7A' : '#01579B')
              .borderRadius(14)
              .onClick(() => {
                if (!this.isLoading) {
                  this.convert();
                }
              })
          }
          .width('90%')
          .padding(20)
          .backgroundColor('#FFFFFF')
          .borderRadius(16)
          .margin({ top: 20, bottom: 20, left: 'auto', right: 'auto' })
          .border({ width: 2, color: '#01579B' })

          // 状态提示卡片
          if (this.message !== '准备就绪') {
            Row() {
              Text(this.message.startsWith('✓') ? '✅' : '⚠️')
                .fontSize(20)
                .margin({ right: 12 })

              Text(this.message)
                .fontSize(14)
                .fontColor(this.message.startsWith('✓') ? '#4ECDC4' : '#FF6B6B')
                .fontWeight(FontWeight.Bold)
                .layoutWeight(1)
            }
            .width('90%')
            .padding(16)
            .backgroundColor(this.message.startsWith('✓') ? '#1a3a3a' : '#3a1a1a')
            .border({ width: 2, color: this.message.startsWith('✓') ? '#4ECDC4' : '#FF6B6B' })
            .borderRadius(14)
            .margin({ bottom: 20, left: 'auto', right: 'auto' })
            .alignItems(VerticalAlign.Center)
          }

          // 结果卡片
          if (this.resultText) {
            Column() {
              Row() {
                Text('📊 Conversion Result')
                  .fontSize(14)
                  .fontWeight(FontWeight.Bold)
                  .fontColor('#01579B')
              }
              .width('100%')
              .padding(14)
              .backgroundColor('#E1F5FE')
              .borderRadius(12)
              .margin({ bottom: 14 })
              .border({ width: 1, color: '#01579B' })

              Text(this.resultText)
                .fontSize(12)
                .fontFamily('monospace')
                .fontColor('#004D7A')
                .width('100%')
                .padding(14)
                .backgroundColor('#E1F5FE')
                .borderRadius(12)
                .border({ width: 1, color: '#0288D1' })
            }
            .width('90%')
            .padding(16)
            .backgroundColor('#E1F5FE')
            .borderRadius(16)
            .margin({ bottom: 20, left: 'auto', right: 'auto' })
            .border({ width: 2, color: '#01579B' })
          }

          // 底部提示
          Column() {
            Row() {
              Text('💡')
                .fontSize(18)
                .margin({ right: 10 })
              
              Text('✈️ Travel Tips')
                .fontSize(14)
                .fontWeight(FontWeight.Bold)
                .fontColor('#01579B')
            }
            .width('100%')
            .margin({ bottom: 12 })

            Text('• Select conversion type\n• Enter value and units\n• Get instant conversion\n• Get travel recommendations')
              .fontSize(12)
              .fontColor('#004D7A')
              .lineHeight(1.6)
          }
          .width('90%')
          .padding(16)
          .backgroundColor('#E1F5FE')
          .borderRadius(16)
          .margin({ bottom: 20, left: 'auto', right: 'auto' })
          .border({ width: 2, color: '#01579B' })

          Blank()
            .height(20)
        }
        .width('100%')
      }
      .layoutWeight(1)
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#E1F5FE')
  }
}

ArkTS 代码详解

这个 ArkTS 组件实现了国际旅行单位转换工具的用户界面。组件使用了 OpenHarmony 的 ArkTS 语言,提供了一个现代化的、旅行蓝色主题的用户界面。

组件定义了五个 @State 属性来存储转换信息:转换类型、数值、源单位和目标单位。这些属性与输入框绑定,当用户输入数据时,这些属性会自动更新。

generateNewCase() 方法生成随机的转换样本,帮助用户快速测试应用。用户可以点击"Random"按钮来生成随机数据。

convert() 方法调用 Kotlin 编译的 JavaScript 函数 travelUnitConverter(),并将转换信息作为参数传递。函数返回的转换结果会显示在结果卡片中。

用户界面包括四个输入框(转换类型、数值、源单位、目标单位)、一个转换按钮、一个状态提示卡片、一个结果卡片和一个提示卡片。所有元素都使用了旅行蓝色主题。


实战案例

案例 1:身高转换

旅行者身高 6 英尺,需要转换为米。输入:height 6 ft m

系统转换结果:

  • 输入:6 ft
  • 输出:1.83 m
  • 评估:身高较高

案例 2:体重转换

旅行者体重 150 磅,需要转换为千克。输入:weight 150 lb kg

系统转换结果:

  • 输入:150 lb
  • 输出:68.04 kg
  • 评估:体重正常

案例 3:温度转换

美国城市温度 98.6°F,需要转换为摄氏度。输入:temperature 98.6 f c

系统转换结果:

  • 输入:98.6 °F
  • 输出:37 °C
  • 天气评估:温暖

案例 4:距离转换

旅行距离 100 英里,需要转换为公里。输入:distance 100 mi km

系统转换结果:

  • 输入:100 mi
  • 输出:160.93 km
  • 旅行建议:美国使用英里,欧洲使用公里

案例 5:体积转换

烹饪需要 2 杯面粉,需要转换为毫升。输入:volume 2 cup ml

系统转换结果:

  • 输入:2 cup
  • 输出:473.18 ml
  • 烹饪建议:美国食谱使用杯,欧洲食谱使用毫升

最佳实践

1. 出国前准备

旅行者应该在出国前熟悉目的地国家的单位制:

  • 美国:使用英制单位(英尺、磅、华氏度、英里)
  • 欧洲:使用公制单位(米、千克、摄氏度、公里)
  • 英国:混合使用英制和公制单位
  • 其他国家:查阅目的地国家的常用单位

2. 日常使用

旅行者在日常生活中应该学会快速转换:

  • 身高和体重:了解自己在不同单位制下的数值
  • 温度:记住常见的温度转换(如 32°F = 0°C)
  • 距离:了解常见的距离转换(如 1 英里 ≈ 1.6 公里)
  • 体积:在烹饪或购物时进行转换

3. 购物和饮食

旅行者在购物和饮食时应该注意单位制的差异:

  • 食品购买:注意包装上的重量单位
  • 烹饪:使用正确的体积单位进行测量
  • 饮料:了解不同国家的饮料容量单位

4. 医疗和健康

旅行者在医疗和健康方面应该了解单位制的差异:

  • 身高和体重:医生可能使用不同的单位制
  • 温度:体温计可能显示不同的单位
  • 药物剂量:确保理解正确的剂量单位

5. 应急情况

旅行者在应急情况下应该能够快速进行单位转换:

  • 距离:了解紧急情况下的距离信息
  • 温度:了解天气和环境温度
  • 体积:了解液体或物质的容量

总结

国际旅行单位转换工具展示了如何使用 Kotlin Multiplatform 技术创建一个功能丰富、跨端兼容的旅行辅助应用。通过支持多种单位制的转换,系统能够帮助旅行者快速适应不同国家的计量习惯。

这个案例不仅展示了 KMP 的强大功能,还演示了如何将实用的旅行知识转化为应用功能。无论是出国旅行、国际商务还是跨境购物,旅行者都可以使用这个工具来快速进行单位转换,避免因为单位制差异而造成的困惑。

国际旅行变得越来越普遍,掌握不同国家的单位制转换是现代旅行者的必备技能。通过使用这个国际旅行单位转换工具,旅行者可以更加自信地探索世界,享受无忧的旅行体验。
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐