鸿蒙+flutter 跨平台开发——快捷记账应用的开发

📱 鸿蒙+Flutter 跨平台开发------快捷记账应用的开发

🚀运行效果展示



🌟 前言

随着移动互联网的快速发展,跨平台开发框架已成为移动应用开发的重要趋势。Flutter 作为 Google 推出的开源跨平台 UI 框架,凭借其"一次编写,处处运行"的特性,受到了广大开发者的青睐。而鸿蒙(HarmonyOS)作为华为自主研发的分布式操作系统,正逐渐成为移动开发领域的新选择。

本文将详细介绍如何使用 Flutter 开发一款支持鸿蒙平台的快捷记账应用,涵盖从架构设计到核心功能实现的全过程。通过这个项目,您将了解到 Flutter 在鸿蒙平台上的开发流程和最佳实践。

📋 应用介绍

🔍 应用定位

快捷记账是一款面向普通用户的个人财务管理应用,旨在帮助用户轻松记录和管理日常收支,提供直观的财务统计分析。

🎯 核心功能

功能模块 描述 图标
交易记录 支持收入和支出的添加、查看、删除 ✏️
分类管理 预设常用收支分类,支持按分类筛选 🏷️
统计分析 提供收支饼图统计,直观展示财务状况 📊
数据持久化 本地存储交易数据,确保数据安全 💾
现代化 UI 采用 Material Design 3,界面简洁美观 🎨

🛠️ 技术栈

技术/框架 版本 用途
Flutter 3.0+ 跨平台 UI 框架
Dart 3.0+ 开发语言
HarmonyOS 3.0+ 目标平台
fl_chart 0.66.0 图表库
shared_preferences 2.2.3 本地数据存储
intl 0.19.0 国际化和日期格式化

🏗️ 核心功能实现

📐 架构设计

应用采用经典的分层架构,主要分为数据层、业务逻辑层和 UI 层:
用户交互
UI层
业务逻辑层
数据层
本地存储

📊 数据模型设计

1. 交易类型枚举
dart 复制代码
/// 交易类型枚举
enum TransactionType {
  income,  // 收入
  expense, // 支出
}
2. 分类模型
dart 复制代码
/// 分类模型
class Category {
  final String id;          // 分类ID
  final String name;        // 分类名称
  final TransactionType type; // 交易类型
  final IconData icon;      // 分类图标

  /// 构造函数
  const Category({
    required this.id,
    required this.name,
    required this.type,
    required this.icon,
  });
}
3. 交易记录模型
dart 复制代码
/// 交易记录模型
class Transaction {
  final String id;              // 交易ID
  final double amount;          // 金额
  final String description;     // 描述
  final Category category;      // 分类
  final DateTime date;          // 日期
  final TransactionType type;   // 交易类型

  /// 构造函数
  const Transaction({
    required this.id,
    required this.amount,
    required this.description,
    required this.category,
    required this.date,
    required this.type,
  });
}

✏️ 核心功能实现

1. 数据持久化

使用 shared_preferences 实现本地数据存储:

dart 复制代码
/// 从本地存储加载交易数据
Future<void> _loadTransactions() async {
  final prefs = await SharedPreferences.getInstance();
  final transactionsJson = prefs.getString('transactions');
  
  if (transactionsJson != null) {
    try {
      final List<dynamic> transactionsList = json.decode(transactionsJson);
      _transactions = transactionsList.map((json) {
        final categoryId = json['categoryId'];
        final category = categories.firstWhere((c) => c.id == categoryId);
        
        return Transaction(
          id: json['id'],
          amount: json['amount'].toDouble(),
          description: json['description'],
          category: category,
          date: DateTime.parse(json['date']),
          type: json['type'] == 'income' 
              ? TransactionType.income 
              : TransactionType.expense,
        );
      }).toList();
    } catch (e) {
      // 加载失败时使用示例数据
      _loadSampleData();
    }
  } else {
    _loadSampleData();
  }
  
  _calculateTotals();
  setState(() {});
}

/// 保存交易数据到本地存储
Future<void> _saveTransactions() async {
  final prefs = await SharedPreferences.getInstance();
  final transactionsJson = json.encode(
    _transactions.map((transaction) => {
      'id': transaction.id,
      'amount': transaction.amount,
      'description': transaction.description,
      'categoryId': transaction.category.id,
      'date': transaction.date.toIso8601String(),
      'type': transaction.type == TransactionType.income ? 'income' : 'expense',
    }).toList(),
  );
  
  await prefs.setString('transactions', transactionsJson);
}
2. 统计分析(饼图实现)

使用 fl_chart 库实现收支统计饼图:

dart 复制代码
/// 构建统计视图
Widget _buildStatisticsView() {
  final expenseData = _prepareChartData(TransactionType.expense);
  final incomeData = _prepareChartData(TransactionType.income);

  return SingleChildScrollView(
    padding: const EdgeInsets.all(16),
    child: Column(
      children: [
        // 支出统计
        Card(
          margin: const EdgeInsets.only(bottom: 16),
          child: Padding(
            padding: const EdgeInsets.all(16),
            child: Column(
              children: [
                const Text(
                  '支出统计',
                  style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
                ),
                const SizedBox(height: 16),
                SizedBox(
                  height: 300,
                  child: PieChart(
                    PieChartData(
                      sections: _buildPieSections(expenseData),
                      sectionsSpace: 2,
                      centerSpaceRadius: 60,
                      pieTouchData: PieTouchData(enabled: true),
                      borderData: FlBorderData(show: false),
                    ),
                  ),
                ),
                const SizedBox(height: 16),
                _buildLegend(expenseData),
              ],
            ),
          ),
        ),
        // 收入统计(类似实现)
        // ...
      ],
    ),
  );
}

/// 构建饼图扇区
List<PieChartSectionData> _buildPieSections(List<CategoryAmount> data) {
  return data.asMap().entries.map((entry) {
    final item = entry.value;
    final fontSize = 16.0;
    final radius = 80.0;

    return PieChartSectionData(
      color: item.color,
      value: item.amount,
      title: item.amount.toStringAsFixed(0),
      radius: radius,
      titleStyle: TextStyle(
        fontSize: fontSize,
        fontWeight: FontWeight.bold,
        color: Colors.white,
      ),
    );
  }).toList();
}
3. 交易记录管理

实现交易记录的添加、查看和删除功能:

dart 复制代码
/// 添加新交易
void _addTransaction(Transaction transaction) {
  setState(() {
    _transactions.add(transaction);
    _calculateTotals();
    _saveTransactions();
  });
}

/// 删除交易
void _deleteTransaction(String id) {
  setState(() {
    _transactions.removeWhere((t) => t.id == id);
    _calculateTotals();
    _saveTransactions();
  });
}

/// 计算总收入和总支出
void _calculateTotals() {
  _totalIncome = _transactions
      .where((t) => t.type == TransactionType.income)
      .fold(0.0, (sum, t) => sum + t.amount);
  _totalExpense = _transactions
      .where((t) => t.type == TransactionType.expense)
      .fold(0.0, (sum, t) => sum + t.amount);
}
4. UI 设计和交互

采用 Material Design 3 设计风格,实现现代化的用户界面:

dart 复制代码
/// 构建首页视图
Widget _buildHomeView() {
  return Column(
    children: [
      // 财务概览卡片
      Card(
        margin: const EdgeInsets.all(16),
        elevation: 4,
        shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)),
        child: Padding(
          padding: const EdgeInsets.all(24),
          child: Column(
            children: [
              const Text(
                '财务概览',
                style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
              ),
              const SizedBox(height: 24),
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceAround,
                children: [
                  // 总收入
                  Expanded(
                    child: Column(
                      children: [
                        const Text(
                          '总收入',
                          style: TextStyle(
                            color: Colors.grey,
                            fontSize: 14,
                          ),
                        ),
                        const SizedBox(height: 8),
                        Text(
                          '¥${_totalIncome.toStringAsFixed(2)}',
                          style: const TextStyle(
                            fontSize: 24,
                            fontWeight: FontWeight.bold,
                            color: Colors.green,
                          ),
                        ),
                      ],
                    ),
                  ),
                  // 分隔线
                  Container(
                    width: 1,
                    height: 60,
                    color: Colors.grey.shade200,
                  ),
                  // 总支出(类似实现)
                  // ...
                  // 结余(类似实现)
                  // ...
                ],
              ),
            ],
          ),
        ),
      ),
      // 交易记录列表(类似实现)
      // ...
    ],
  );
}

🚀 鸿蒙平台适配

1. 配置 pubspec.yaml
yaml 复制代码
name: flutter_text
description: A new Flutter project.
publish_to: "none"

version: 1.0.0+1

environment:
  sdk: ^3.6.2

dependencies:
  flutter:
    sdk: flutter
  cupertino_icons: ^1.0.8
  fl_chart: ^0.66.0
  shared_preferences: ^2.2.3
  intl: ^0.19.0

flutter:
  uses-material-design: true
2. 构建鸿蒙应用

使用 Flutter 命令构建鸿蒙 HAP 包:

bash 复制代码
flutter run

📝 开发过程中的挑战与解决方案

1. 图表库兼容性问题

问题 :初始使用的 charts_flutter 库与 Dart 3.0 不兼容,导致编译错误。

解决方案 :替换为 fl_chart 库,该库具有更好的 Dart 3.0 兼容性和更现代化的 API 设计。

2. UI 溢出问题

问题:在小屏幕设备上,交易记录卡片和财务概览卡片出现文字溢出。

解决方案

  • 为文本添加容器约束和溢出处理
  • 优化布局结构,合理分配空间
  • 调整字体大小和间距

3. 鸿蒙平台调试问题

问题:鸿蒙模拟器的调试连接不稳定,经常出现连接断开的情况。

解决方案

  • 确保使用最新版本的鸿蒙 SDK 和 Flutter 插件
  • 采用非阻塞式构建命令,先构建 HAP 包,再手动安装到设备
  • 重点关注编译错误,确保代码质量

🎯 总结

📈 项目优势

  1. 跨平台开发优势:使用 Flutter 开发鸿蒙应用,实现了"一次编写,处处运行",大大提高了开发效率。
  2. 数据可视化 :通过 fl_chart 库,实现了直观的财务统计图表,提升了应用的价值。
  3. 本地数据存储 :使用 shared_preferences 实现了可靠的数据持久化,确保用户数据安全。

📌 未来改进方向

  1. 云同步功能:添加云存储支持,实现多设备数据同步。
  2. 数据导出功能:支持将交易数据导出为 CSV 或 Excel 格式。
  3. 预算管理:添加预算设置和提醒功能。
  4. 深色模式:支持深色主题,提升夜间使用体验。
  5. 国际化支持:添加多语言支持,扩大应用的适用范围。

通过本文的介绍,相信您对鸿蒙+Flutter 跨平台开发有了更深入的了解。希望这篇文章能够帮助您在跨平台开发之路上走得更远,开发出更多优秀的移动应用!🚀

如果您有任何问题或建议,欢迎在评论区留言讨论。😊


欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

相关推荐
向前V2 小时前
Flutter for OpenHarmony数独游戏App实战:胜利弹窗
java·flutter·游戏
Felven2 小时前
华为鲲鹏920s处理器在统信系统下接收外部GPIO中断问题
华为·统信·鲲鹏920s·gpio中断
菜鸟小芯2 小时前
【开源鸿蒙跨平台开发先锋训练营】DAY4~DAY6 OpenHarmony版Flutter本地美食清单上拉加载 + 下拉刷新 + 数据加载提示实现
flutter·harmonyos
funnycoffee1232 小时前
思科,华为,华三交换机清空端口配置命令
华为·清空接口配置
猛扇赵四那边好嘴.2 小时前
Flutter 框架跨平台鸿蒙开发 - 诗词鉴赏应用开发教程
flutter·华为·harmonyos
funnycoffee1233 小时前
华为USG防火墙 直连 ping不通是啥问题?以及策略查看命令
华为·华为usg·usg直连不通
IT陈图图3 小时前
跨端之旅:Flutter × OpenHarmony 构建旅行记录应用的搜索栏
flutter·开源·鸿蒙·openharmony
—Qeyser3 小时前
Flutter组件 - BottomNavigationBar 底部导航栏
开发语言·javascript·flutter
时光慢煮3 小时前
行旅迹 · 基于 Flutter × OpenHarmony 的旅行记录应用— 构建高体验旅行记录列表视图的跨端实践
flutter·华为·开源·openharmony