Flutter集成三方库开发鸿蒙6.0(API20+)本地记账APP实战案例
本地记账APP是日常高频使用的工具类应用,本文基于Flutter + 鸿蒙6.0(API20+)环境,以本地记账APP为实战载体,详细讲解如何集成适配鸿蒙系统的三方库,实现账单添加、收支分类、余额统计、数据持久化等完整功能,代码全程带注释,可直接复制运行,助力开发者快速掌握Flutter跨端开发鸿蒙应用的核心流程。本文通过Flutter集成三方库开发鸿蒙本地记账APP的实战案例,完整覆盖了从环境配
欢迎加入开源鸿蒙跨平台社区: https://openharmonycrossplatform.csdn.net
前言
本地记账APP是日常高频使用的工具类应用,本文基于 Flutter + 鸿蒙6.0(API20+) 环境,以本地记账APP为实战载体,详细讲解如何集成适配鸿蒙系统的三方库,实现账单添加、收支分类、余额统计、数据持久化等完整功能,代码全程带注释,可直接复制运行,助力开发者快速掌握Flutter跨端开发鸿蒙应用的核心流程。
一、开发环境准备
1.1 基础环境配置
- Flutter SDK:3.16.0 及以上版本
- DevEco Studio:5.0.1 及以上版本
- 鸿蒙 SDK:API20(HarmonyOS 6.0)
- 开发编辑器:VS Code / Android Studio
- 鸿蒙真机/模拟器(API20+)
1.2 Flutter鸿蒙环境启用
执行以下命令,开启Flutter对鸿蒙平台的支持,并验证环境是否正常:
# 启用鸿蒙平台支持
flutter config --enable-openharmony
# 验证环境(确保OpenHarmony相关无报错)
flutter doctor
二、项目创建与鸿蒙基础配置
2.1 创建Flutter项目
通过命令行创建支持鸿蒙平台的Flutter项目,命名为本地记账APP相关名称:
# 创建项目
flutter create flutter_harmony_account
# 进入项目目录
cd flutter_harmony_account
2.2 鸿蒙SDK版本适配
修改项目中 openharmony/app/build.gradle 文件,配置鸿蒙API20相关参数,确保适配鸿蒙6.0系统:
openharmony {
compileSdkVersion 20 // 鸿蒙6.0对应API20
defaultConfig {
minSdkVersion 20 // 最低支持鸿蒙6.0
targetSdkVersion 20
versionCode 1
versionName "1.0"
}
}
三、鸿蒙兼容三方库集成
本次记账APP选用3个稳定兼容鸿蒙6.0的常用三方库,覆盖数据持久化、消息提示、时间/金额格式化核心需求,具体如下:
| 三方库名称 | 推荐版本 | 核心功能 |
|---|---|---|
| shared_preferences | ^2.2.2 | 本地数据持久化,保存账单记录(鸿蒙兼容) |
| fluttertoast | ^8.2.8 | 鸿蒙平台轻量级消息提示(适配鸿蒙系统弹窗) |
| intl | ^0.18.1 | 时间格式化、金额保留两位小数,统一展示格式 |
3.1 添加依赖并安装
打开项目根目录的 pubspec.yaml 文件,在 dependencies 节点下添加三方库依赖:
dependencies:
flutter:
sdk: flutter
# 本地数据持久化(保存账单)
shared_preferences: ^2.2.2
# 鸿蒙消息提示
fluttertoast: ^8.2.8
# 时间、金额格式化
intl: ^0.18.1
添加完成后,执行以下命令安装依赖:
flutter pub get
四、完整功能代码实现(可直接运行)
新建并修改 lib/main.dart 文件,写入完整代码(全程带注释,新手可快速理解),实现账单添加、删除、收支分类、余额统计、数据持久化等核心功能:
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:intl/intl.dart';
import 'dart:convert';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter鸿蒙本地记账',
theme: ThemeData(primarySwatch: Colors.blue),
home: const AccountPage(),
// 关闭调试标签,适配正式展示
debugShowCheckedModeBanner: false,
);
}
}
// 记账主页面
class AccountPage extends StatefulWidget {
const AccountPage({super.key});
State<AccountPage> createState() => _AccountPageState();
}
class _AccountPageState extends State<AccountPage> {
// 金额输入控制器
final TextEditingController _amountController = TextEditingController();
// 备注输入控制器
final TextEditingController _noteController = TextEditingController();
// 账单列表(存储所有账单数据)
List<Map<String, dynamic>> _accountList = [];
// 本地存储实例(shared_preferences)
late SharedPreferences _prefs;
// 收支类型:true=收入,false=支出
bool _isIncome = false;
// 页面初始化:加载本地存储的账单数据
void initState() {
super.initState();
_initPrefs();
}
// 初始化本地存储,加载历史账单
Future<void> _initPrefs() async {
_prefs = await SharedPreferences.getInstance();
_loadAccounts();
}
// 加载本地账单数据(从shared_preferences读取)
void _loadAccounts() {
setState(() {
// 读取存储的字符串列表,无数据则返回null
List<String>? savedAccounts = _prefs.getStringList('accountList');
if (savedAccounts != null) {
// 将字符串转为Map对象,存入账单列表
_accountList = savedAccounts.map((e) => jsonDecode(e)).toList();
}
});
}
// 添加账单(核心方法)
Future<void> _addAccount() async {
// 获取输入的金额和备注,去除空格
String amountStr = _amountController.text.trim();
String note = _noteController.text.trim();
// 校验:金额不能为空
if (amountStr.isEmpty) {
Fluttertoast.showToast(msg: "请输入记账金额");
return;
}
// 将金额转为double类型(保留两位小数)
double amount = double.parse(amountStr);
// 格式化当前时间(yyyy-MM-dd HH:mm)
String time = DateFormat('yyyy-MM-dd HH:mm').format(DateTime.now());
// 构建账单对象
Map<String, dynamic> account = {
'amount': amount, // 金额
'isIncome': _isIncome, // 收支类型
'note': note, // 备注
'time': time // 记账时间
};
// 更新页面状态,添加新账单
setState(() {
_accountList.add(account);
// 清空输入框
_amountController.clear();
_noteController.clear();
});
// 保存账单到本地存储
await _saveAccounts();
// 鸿蒙平台提示:添加成功
Fluttertoast.showToast(msg: "账单添加成功");
}
// 保存账单到本地存储(shared_preferences)
Future<void> _saveAccounts() async {
// 将账单列表转为字符串列表(shared_preferences不支持直接存储Map)
List<String> accountStrList = _accountList.map((e) => jsonEncode(e)).toList();
// 存入本地存储
await _prefs.setStringList('accountList', accountStrList);
}
// 删除账单
Future<void> _deleteAccount(int index) async {
setState(() {
_accountList.removeAt(index);
});
// 更新本地存储
await _saveAccounts();
// 鸿蒙提示:删除成功
Fluttertoast.showToast(msg: "账单删除成功");
}
// 计算当前余额(收入-支出)
double _calculateBalance() {
double balance = 0.0;
for (var account in _accountList) {
if (account['isIncome']) {
balance += account['amount']; // 收入加金额
} else {
balance -= account['amount']; // 支出减金额
}
}
return balance;
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Flutter+鸿蒙 本地记账"),
centerTitle: true,
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
// 金额输入框
TextField(
controller: _amountController,
keyboardType: TextInputType.numberWithOptions(decimal: true),
decoration: const InputDecoration(
hintText: "请输入金额(例:100.00)",
border: OutlineInputBorder(),
labelText: "金额",
),
),
const SizedBox(height: 12),
// 备注输入框
TextField(
controller: _noteController,
decoration: const InputDecoration(
hintText: "请输入备注(例:吃饭、工资)",
border: OutlineInputBorder(),
labelText: "备注",
),
),
const SizedBox(height: 12),
// 收支类型切换(开关)
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
const Text("收支类型:"),
const SizedBox(width: 10),
Switch(
value: _isIncome,
onChanged: (value) {
// 切换收支类型,更新页面
setState(() {
_isIncome = value;
});
},
),
const SizedBox(width: 10),
// 显示当前收支类型
Text(_isIncome ? "收入" : "支出", style: const TextStyle(fontSize: 16)),
],
),
const SizedBox(height: 16),
// 添加账单按钮
SizedBox(
width: double.infinity,
child: ElevatedButton(
onPressed: _addAccount,
child: const Text("添加账单", style: TextStyle(fontSize: 16)),
),
),
const SizedBox(height: 20),
// 当前余额展示
Text(
"当前余额:¥${_calculateBalance().toStringAsFixed(2)}",
style: const TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: Colors.green,
),
),
const Divider(height: 20),
// 账单列表(滚动展示)
Expanded(
child: _accountList.isEmpty
? const Center(
child: Text(
"暂无账单,快去添加吧~",
style: TextStyle(fontSize: 16, color: Colors.grey),
),
)
: ListView.builder(
itemCount: _accountList.length,
itemBuilder: (context, index) {
var account = _accountList[index];
return ListTile(
// 记账时间
title: Text(account['time']),
// 备注
subtitle: Text(account['note']),
// 金额(收入红色,支出绿色)
trailing: Text(
"${account['isIncome'] ? '+' : '-'}¥${account['amount'].toStringAsFixed(2)}",
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
color: account['isIncome'] ? Colors.green : Colors.red,
),
),
// 长按删除账单
onLongPress: () => _deleteAccount(index),
);
},
),
),
],
),
),
);
}
}
五、鸿蒙6.0(API20+)专属适配
5.1 鸿蒙权限配置
由于APP需要使用本地存储保存账单数据,需在 openharmony/app/src/main/module.json5 文件中添加鸿蒙API20规范的存储权限,否则会导致数据无法保存:
{
"module": {
// 其他配置不变,添加以下权限配置
"requestPermissions": [
{
"name": "ohos.permission.WRITE_LOCAL_STORAGE",
"reason": "用于保存记账账单数据"
},
{
"name": "ohos.permission.READ_LOCAL_STORAGE",
"reason": "用于读取历史记账账单"
}
]
}
}
5.2 鸿蒙屏幕适配
适配鸿蒙全面屏、折叠屏,避免界面被系统导航栏遮挡,在 lib/main.dart 的 MaterialApp 中添加以下代码:
builder: (context, child) {
return MediaQuery(
data: MediaQuery.of(context).copyWith(
viewPadding: EdgeInsets.zero, // 忽略系统底部导航栏遮挡
),
child: child!,
);
},
六、项目编译与运行
6.1 运行准备
- 连接鸿蒙6.0真机(开启开发者模式 + USB调试),或启动鸿蒙6.0模拟器;
- 打开命令行,进入项目根目录;
- 执行以下命令查看已连接的鸿蒙设备:
flutter devices
6.2 执行运行
复制上一步查看的设备ID,执行以下命令运行项目:
flutter run -d 设备ID
等待编译完成后,APP会自动安装到鸿蒙设备/模拟器中,即可正常使用。
七、功能效果验证
确保以下核心功能正常运行,符合鸿蒙6.0设备适配要求:
- ✅ 输入金额、备注,切换收支类型,点击“添加账单”可成功添加;
- ✅ 鸿蒙设备弹出Toast提示(添加成功、删除成功);
- ✅ 账单列表正常展示,长按可删除账单;
- ✅ 余额实时计算,收入/支出金额颜色区分;
- ✅ 重启APP后,账单数据不丢失(本地持久化生效);
- ✅ 界面适配鸿蒙全面屏,无遮挡问题。
八、常见问题与解决方案
问题1:账单无法保存,提示“无权限”
解决方案:检查 module.json5 中的存储权限是否添加,重启APP并在设备上授权存储权限。
问题2:三方库在鸿蒙上不生效(如Toast不弹出)
解决方案:执行 flutter pub upgrade 更新三方库到最新稳定版,确保版本兼容鸿蒙API20。
问题3:APP启动白屏
解决方案:检查 openharmony/app/build.gradle 中 minSdkVersion 是否设置为20,确认鸿蒙设备/模拟器版本≥6.0。
问题4:金额输入异常(无法输入小数)
解决方案:确保 TextField 的 keyboardType 设置为 TextInputType.numberWithOptions(decimal: true),支持小数输入。
总结
本文通过 Flutter集成三方库开发鸿蒙本地记账APP 的实战案例,完整覆盖了从环境配置、项目创建、三方库集成,到功能开发、鸿蒙适配、运行测试的全流程。借助 shared_preferences 实现数据持久化,fluttertoast 适配鸿蒙消息提示,intl 统一格式展示,大幅简化了开发流程,同时保证了APP在鸿蒙6.0(API20+)设备上的稳定性和兼容性。
该案例代码可直接复用,开发者可在此基础上扩展更多功能(如账单分类、月度统计等),是Flutter+鸿蒙跨端开发入门的优质实战模板。
接下来我继续为你生成第四篇:图片浏览器APP文章吗?
更多推荐




所有评论(0)