Flutter 鸿蒙:利用三方库构建单位转换器
Flutter 鸿蒙开发实践:利用三方库构建跨端极简单位转换器
Flutter 鸿蒙开发实践:利用三方库构建跨端极简单位转换器
欢迎加入开源鸿蒙跨平台社区: https://openharmonycrossplatform.csdn.net
1. 前言
对于刚入门的 \\ 鸿蒙(HarmonyOS)\\ 开发者,掌握数据流转和 UI 交互是核心能力。Flutter 作为跨端应用开发框架,能高效实现一套代码同时适配鸿蒙、Android、iOS 等多端系统,大幅降低开发与维护成本。
本文将以极简单位转换器为实战案例,手把手带你完成:
-
Flutter 集成
font\_awesome\_flutter图标库 -
使用
intl实现高精度数值格式化 -
在无真机环境下,通过 HarmonyOS Next 虚拟机开发调试
-
解决鸿蒙编译常见配置报错(bundleName 不匹配、Schema 校验失败)
2. 核心关键词
-
Flutter:跨平台 UI 框架,一套代码多端运行
-
font_awesome_flutter:提供精美矢量图标,提升界面视觉效果
-
intl:数字格式化、小数位保留、国际化处理
-
HarmonyOS Next:鸿蒙下一代系统,支持 Flutter 跨端运行
-
单位转换:长度(厘米 ↔ 英寸)、重量(公斤 ↔ 磅)
3. 环境准备
3.1 开发环境
-
Flutter SDK(建议 3.10.0 及以上)
-
DevEco Studio(鸿蒙开发 IDE)
-
HarmonyOS Next 虚拟机
-
已配置 Flutter 鸿蒙编译环境
3.2 项目依赖配置
在项目根目录 pubspec\.yaml 中添加:
dependencies:
flutter:
sdk: flutter
# 精美图标库
font_awesome_flutter: ^10.7.0
# 数字格式化
intl: ^0.19.0
flutter:
uses-material-design: true
执行安装命令:
flutter pub get
4. 项目设计
4.1 功能清单
-
长度单位转换:厘米 ↔ 英寸
-
重量单位转换:公斤 ↔ 磅
-
输入数值校验
-
结果保留两位小数
-
鸿蒙简约风格 UI
-
支持虚拟机 / 真机运行
4.2 界面结构
-
顶部标题栏(带图标)
-
转换类型切换(长度 / 重量)
-
数字输入框
-
转换按钮
-
结果展示区域
5. 完整代码实现
5.1 单位转换工具类
新建路径:lib/utils/unit\_converter\.dart
/// 通用单位转换工具类
class UnitConverter {
/// 长度:厘米 → 英寸
static double cmToInch(double cm) {
return cm * 0.393701;
}
/// 长度:英寸 → 厘米
static double inchToCm(double inch) {
return inch * 2.54;
}
/// 重量:公斤 → 磅
static double kgToLb(double kg) {
return kg * 2.20462;
}
/// 重量:磅 → 公斤
static double lbToKg(double lb) {
return lb * 0.453592;
}
}
5.2 主页面代码
替换文件:lib/main\.dart
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:intl/intl.dart';
import 'utils/unit_converter.dart';
void main() {
runApp(const UnitConverterApp());
}
class UnitConverterApp extends StatelessWidget {
const UnitConverterApp({super.key});
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter 鸿蒙单位转换器',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: const HomePage(),
);
}
}
class HomePage extends StatefulWidget {
const HomePage({super.key});
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
// 转换类型
enum ConvertType { length, weight }
ConvertType _currentType = ConvertType.length;
// 输入与结果
final TextEditingController _inputController = TextEditingController();
String _result = '请输入数字并转换';
// 保留两位小数
final NumberFormat _format = NumberFormat('#0.00');
// 转换逻辑
void _doConvert() {
String inputText = _inputController.text.trim();
if (inputText.isEmpty) {
setState(() => _result = '请输入有效数字');
return;
}
double? input = double.tryParse(inputText);
if (input == null) {
setState(() => _result = '输入格式不正确');
return;
}
double output;
String unitFrom, unitTo;
if (_currentType == ConvertType.length) {
output = UnitConverter.cmToInch(input);
unitFrom = '厘米';
unitTo = '英寸';
} else {
output = UnitConverter.kgToLb(input);
unitFrom = '公斤';
unitTo = '磅';
}
setState(() {
_result = '$input $unitFrom = ${_format.format(output)} $unitTo';
});
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
leading: const FaIcon(FontAwesomeIcons.rulerCombined),
title: const Text('极简单位转换器'),
),
body: SingleChildScrollView(
padding: const EdgeInsets.all(16),
child: Column(
children: [
// 类型切换
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
_typeItem(
icon: FontAwesomeIcons.ruler,
label: '长度',
type: ConvertType.length,
),
const SizedBox(width: 40),
_typeItem(
icon: FontAwesomeIcons.weightScale,
label: '重量',
type: ConvertType.weight,
),
],
),
const SizedBox(height: 30),
// 输入框
TextField(
controller: _inputController,
keyboardType: const TextInputType.numberWithOptions(decimal: true),
decoration: const InputDecoration(
labelText: '请输入数值',
border: OutlineInputBorder(),
prefixIcon: FaIcon(FontAwesomeIcons.calculator),
),
),
const SizedBox(height: 20),
// 转换按钮
SizedBox(
width: double.infinity,
child: ElevatedButton(
onPressed: _doConvert,
child: const Padding(
padding: EdgeInsets.all(14),
child: Text('开始转换', style: TextStyle(fontSize: 16)),
),
),
),
const SizedBox(height: 30),
// 结果展示
Container(
width: double.infinity,
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.grey.shade100,
borderRadius: BorderRadius.circular(8),
),
child: Text(
_result,
style: const TextStyle(fontSize: 18),
textAlign: TextAlign.center,
),
),
],
),
),
);
}
// 类型选择组件
Widget _typeItem({
required IconData icon,
required String label,
required ConvertType type,
}) {
bool isSelected = _currentType == type;
return GestureDetector(
onTap: () => setState(() => _currentType = type),
child: Column(
children: [
FaIcon(
icon,
size: 36,
color: isSelected ? Colors.blue : Colors.grey,
),
const SizedBox(height: 6),
Text(
label,
style: TextStyle(
fontSize: 15,
color: isSelected ? Colors.blue : Colors.grey,
fontWeight: isSelected ? FontWeight.bold : FontWeight.normal,
),
),
],
),
);
}
}
6. 鸿蒙运行与配置
6.1 运行项目
flutter run -d harmony
6.2 必须配置:app.json5
在 ohos/ 目录下创建 app\.json5:
{
"app": {
"bundleName": "com.example.flutter_harmonyos4",
"vendor": "example",
"versionCode": 1,
"versionName": "1.0.0"
}
}
6.3 常见报错解决
报错:bundleName 不匹配
-
原因:签名配置与包名不一致
-
解决:删除
build\-profile\.json5中旧 signingConfigs,Clean → Rebuild
报错:Schema validate failed
-
原因:
module\.json5不能写app或bundleName -
解决:保持
module\.json5为默认结构
7. 扩展功能方向
-
增加温度、面积、体积、时间等单位
-
支持反向转换
-
添加历史记录列表
-
适配鸿蒙深色模式
-
支持一键复制结果
-
增加输入清空按钮
8. 总结
本文通过极简单位转换器完整案例,覆盖了 Flutter 鸿蒙开发的核心知识点:
-
三方库(图标、数字格式化)集成
-
鸿蒙项目结构与配置规范
-
数据处理、UI 交互、状态管理
-
虚拟机调试 + 常见报错解决方案
运行截图:
更多推荐


所有评论(0)