一、为什么需要“简易单位换算器”?
在 OpenHarmony 的 IoT 和生活场景中,用户常需进行简单单位换算:
- 装修时将“厘米”转为“米”;
- 购物时比较“150cm 衣服”与“1.6m 身高”;
- 教育场景中学习公制单位关系。
虽然手机自带计算器可完成,但专用界面能降低认知负荷——用户无需记住“1 米 = 100 厘米”,只需选择单位、输入数字、点击转换。
更重要的是,此类功能完全基于确定性数学运算,不依赖网络、不读取传感器、不申请权限,是展示“纯逻辑 UI”的理想范例。
本文将构建一个极简页面:「简易单位换算器」。它只包含:
- 一个数字输入框(用于输入数值);
- 两个 Radio 按钮(“米 → 厘米” 或 “厘米 → 米”);
- 一个“转换”按钮;
- 一行结果显示区(如 “1.5 米 = 150 厘米”)。
所有逻辑基于乘除 100,无浮点精度处理(保留默认格式),确保简单可靠。
二、完整可运行代码
// lib/main.dartimport'package:flutter/material.dart';voidmain(){runApp(constMyApp());}classMyAppextendsStatelessWidget{constMyApp({super.key});@overrideWidgetbuild(BuildContextcontext){returnMaterialApp(title:'单位换算',debugShowCheckedModeBanner:false,theme:ThemeData(useMaterial3:true,colorScheme:ColorScheme.fromSeed(seedColor:Colors.indigo)),home:constUnitConverterPage(),);}}enumConvertDirection{meterToCm,cmToMeter}classUnitConverterPageextendsStatefulWidget{constUnitConverterPage({super.key});@overrideState<UnitConverterPage>createState()=>_UnitConverterPageState();}class_UnitConverterPageStateextendsState<UnitConverterPage>{finalTextEditingController_controller=TextEditingController();ConvertDirection_direction=ConvertDirection.meterToCm;String_result='';void_convert(){finalinputText=_controller.text;if(inputText.isEmpty){setState((){_result='请输入数字';});return;}double?value=double.tryParse(inputText);if(value==null){setState((){_result='请输入有效数字';});return;}Stringoutput;if(_direction==ConvertDirection.meterToCm){output='${value}米 =${value*100}厘米';}else{output='${value}厘米 =${value/100}米';}setState((){_result=output;});}@overrideWidgetbuild(BuildContextcontext){returnScaffold(appBar:AppBar(title:constText('简易单位换算器')),body:Padding(padding:constEdgeInsets.all(20),child:Column(children:[TextField(controller:_controller,keyboardType:TextInputType.numberWithOptions(decimal:true),decoration:constInputDecoration(labelText:'输入数值'),),constSizedBox(height:16),Row(children:[Text('转换方向: '),Radio<ConvertDirection>(value:ConvertDirection.meterToCm,groupValue:_direction,onChanged:(ConvertDirection?v){if(v!=null){setState((){_direction=v;});}},),constText('米 → 厘米'),constSizedBox(width:24),Radio<ConvertDirection>(value:ConvertDirection.cmToMeter,groupValue:_direction,onChanged:(ConvertDirection?v){if(v!=null){setState((){_direction=v;});}},),constText('厘米 → 米'),],),constSizedBox(height:24),ElevatedButton(onPressed:_convert,child:constText('转换')),constSizedBox(height:24),Text(_result,style:constTextStyle(fontSize:18)),],),),);}}三、设计原则:简单,即是可靠
单位换算是确定性计算——给定输入,必有唯一输出。因此,UI 应聚焦于:
- 输入明确:数字键盘 + 清晰标签;
- 方向清晰:Radio 按钮避免歧义;
- 反馈即时:错误提示(空/非数字)与成功结果共用同一区域。
这种“输入-操作-输出”三段式结构,是工具类应用的黄金模板。
四、安全数字解析与转换逻辑:
我们首先看核心转换函数:
void_convert(){finalinputText=_controller.text;if(inputText.isEmpty){setState((){_result='请输入数字';});return;}double?value=double.tryParse(inputText);if(value==null){setState((){_result='请输入有效数字';});return;}Stringoutput;if(_direction==ConvertDirection.meterToCm){output='${value}米 =${value*100}厘米';}else{output='${value}厘米 =${value/100}米';}setState((){_result=output;});}这段代码实现了健壮的输入处理与换算。
- 空输入检查:先判断
isEmpty,避免tryParse对空串返回null; double.tryParse:- 是 Dart 标准库方法,安全解析字符串为
double?; - 支持整数(“5”)和小数(“1.5”);
- 若失败(如 “abc”),返回
null;
- 是 Dart 标准库方法,安全解析字符串为
- 分支逻辑:
- 使用
enum值比较,类型安全; - 乘 100 或除 100,符合公制单位定义;
- 使用
- 字符串插值:
- 直接使用
${value},Dart 自动格式化浮点数; - 虽未处理精度(如 1.0 显示为 “1.0”),但对简易工具足够。
- 直接使用
💡 此设计不隐藏错误,而是明确告知用户“哪里错了”,提升可用性。
五、Radio 按钮状态管理:
再看方向选择 UI:
Radio<ConvertDirection>(value:ConvertDirection.meterToCm,groupValue:_direction,onChanged:(ConvertDirection?v){if(v!=null){setState((){_direction=v;});}},),这里展示了类型安全的单选控件用法。
enum ConvertDirection:- 定义两种转换方向,避免魔法字符串;
- 编译期检查,防止拼写错误;
groupValue: _direction:- 当前选中值由状态变量
_direction控制;
- 当前选中值由状态变量
onChanged回调:- 参数
v可能为null(理论上不会,但 API 设计如此); - 显式检查
if (v != null)是良好实践; - 调用
setState更新状态,触发 Radio 重绘。
- 参数
📌 值得注意的是,未使用
RadioListTile以减少嵌套,保持布局扁平,更适合水平排列。
六、为何这个微工具值得存在?
1. 教育价值
- 向初学者展示
TextField、Radio、StatefulWidget的组合使用; - 演示
double.tryParse的安全数字处理模式。
2. 实用场景
- 快速换算装修尺寸;
- 辅助儿童学习单位关系;
- 作为更大换算器(如长度、重量、温度)的原型。
3. 工程示范
- 展示如何用最少代码实现完整输入-验证-输出流程;
- 体现“错误即反馈”的 UX 原则。
更重要的是,它完全自包含——不联网、不存档、不依赖外部状态,关闭即忘,符合隐私优先理念。
七、扩展与限制
可安全扩展的方向:
- 增加单位:如毫米、千米;
- 格式化输出:
value.toStringAsFixed(2)保留两位小数; - 历史记录:用
ListView显示最近 5 次结果。
当前限制(有意为之):
- 不支持负数(生活场景通常为正);
- 不自动清空输入(用户可连续转换);
- 不记忆上次方向(每次启动默认“米→厘米”)。
这些限制确保核心功能极致简单、无认知负担。
八、结语:可靠的工具,源于确定的逻辑
本文的页面完整实现了一个实用、安全、直观的单位换算器。它没有炫技,没有复杂架构,只有清晰的输入、确定的计算、明确的输出。
在 OpenHarmony 的智慧世界中,我们常追求“智能”与“协同”,但不应忘记:最值得信赖的功能,往往是那些简单到不会出错的那一个。
让我们继续用这样的微工具,让技术真正服务于日常。
🌐欢迎加入开源鸿蒙跨平台社区:
https://openharmonycrossplatform.csdn.net/
在这里,您将获得:
- OpenHarmony 工具类应用设计规范;
- Flutter 输入验证与状态管理模板;
- 无依赖实用组件实战指南。
用简单,成就可靠。