基于 Harmony 6.0 应用的个人记账本应用首页实现

前言

记账是一个"明明很重要但绝大多数人坚持不了"的事——一开始下载 App 雄心壮志,几天后就忘了。一款好的记账应用要把"今天花了多少 / 这月超支了吗 / 哪个分类花最多 / 怎么快速记账"四件事在一屏内全部铺到。Harmony 6.0 时代,记账类应用迎来了几个独特的能力红利——HMS Wallet 让支付凭证自动同步、AI 助手能力让"昨天午饭花了 38" 语音记账成为可能、桌面服务卡片让"本月已花"在桌面常驻、分布式数据让多端账本同步。本文用 Flutter 在 Harmony 6.0 上实现一个个人记账本首页。

背景

记账类应用的视觉关键词是"清爽、简洁、激励"——靛蓝色 #6366F1 配青色 #14B8A6 是这类应用的合适主色。本项目首页 5 个模块:渐变 Header(本月已花 + 大记账按钮)、本周收支柱状图、分类支出占比饼图、最近记账列表、本月预算进度。
在这里插入图片描述

Flutter × Harmony 6.0 跨端开发介绍

Harmony 6.0 在记账类应用上的能力栈完整——HMS Wallet 自动同步支付凭证(用户授权后免手动)、AI 助手能力提供语音记账、分布式数据让多端账本同步、PushKit 提供"该记账了"提醒、桌面服务卡片让收支可视化常驻。

开发核心代码

代码一:本月已花 Header

Widget _header() {
  return Container(
    padding: const EdgeInsets.all(20),
    decoration: BoxDecoration(
      gradient: const LinearGradient(
        colors: [_primary, Color(0xFF4338CA)],
        begin: Alignment.topLeft, end: Alignment.bottomRight),
      borderRadius: BorderRadius.circular(24),
    ),
    child: Column(crossAxisAlignment: CrossAxisAlignment.start,
        children: [
      const Row(children: [
        Icon(Icons.account_balance_wallet,
            color: Colors.white, size: 22),
        SizedBox(width: 8),
        Text('小账本',
            style: TextStyle(color: Colors.white,
                fontSize: 18, fontWeight: FontWeight.w800)),
        Spacer(),
        Icon(Icons.calendar_month,
            color: Colors.white, size: 22),
      ]),
      const SizedBox(height: 14),
      const Text('本月已花',
          style: TextStyle(color: Colors.white70, fontSize: 13)),
      const SizedBox(height: 4),
      const Text('¥ 4,286.50',
          style: TextStyle(color: Colors.white,
              fontSize: 38, fontWeight: FontWeight.w900)),
      const SizedBox(height: 4),
      const Row(children: [
        Icon(Icons.trending_down,
            color: Colors.white70, size: 14),
        SizedBox(width: 4),
        Text('比上月省了 ¥386 · 预算还剩 ¥1,714',
            style: TextStyle(color: Colors.white70, fontSize: 12)),
      ]),
      const SizedBox(height: 14),
      Row(children: [
        Expanded(child: Container(height: 50,
          decoration: BoxDecoration(color: Colors.white,
              borderRadius: BorderRadius.circular(25)),
          child: const Center(child: Row(
            mainAxisSize: MainAxisSize.min,
            children: [
              Icon(Icons.add, color: _primary, size: 22),
              SizedBox(width: 6),
              Text('记一笔',
                  style: TextStyle(color: _primary,
                      fontSize: 14, fontWeight: FontWeight.w800)),
            ],
          )),
        )),
        const SizedBox(width: 10),
        Container(width: 50, height: 50,
          decoration: BoxDecoration(
            color: Colors.white.withValues(alpha: 0.22),
            borderRadius: BorderRadius.circular(25)),
          child: const Icon(Icons.mic, color: Colors.white, size: 22),
        ),
      ]),
    ]),
  );
}

语音记账按钮通过 AudioKit 录音 + AI 助手能力 ASR 识别 + NLU 解析金额和分类,5 秒内完成一条记账。"昨天午饭花了 38"自动解析为:日期=昨天、分类=餐饮、金额=38。这种端侧 AI 让记账门槛降到极低。

从「本月已花 Header」的财务可视化与消费监控设计角度再补一段。个人记账类应用的 Header 必须把「我这个月花了多少 / 还能花多少」做成视觉中心。这段 Header 用靛蓝到深紫的渐变背景(专业色),配合「本月已花 ¥X / 预算 ¥Y」+ 进度条 + 「快速记账」按钮的多段式排版,让用户每次打开应用都能掌握财务状况。如果消费已超预算,让背景变橙红警示。如果未来要扩展支持「按账户切换」(工资卡、信用卡、储蓄卡分别记),可以在 Header 加 chip 切换栏。鸿蒙 6.0 的 AI 助手让"语音一句话记账"变成现实——用户开车走路时也能说一句就完成。

代码二:本周收支柱状图

Widget _weekChart() {
  final exp = const [128, 86, 156, 92, 218, 246, 168];
  final maxVal = exp.reduce((a, b) => a > b ? a : b);
  return Container(padding: const EdgeInsets.all(16),
    decoration: BoxDecoration(color: _card,
        borderRadius: BorderRadius.circular(16)),
    child: Column(crossAxisAlignment: CrossAxisAlignment.start,
        children: [
      const Row(children: [
        Text('本周支出',
            style: TextStyle(color: _ink, fontSize: 14,
                fontWeight: FontWeight.w700)),
        Spacer(),
        Text('共 ¥ 1,094',
            style: TextStyle(color: _primary, fontSize: 13,
                fontWeight: FontWeight.w800)),
      ]),
      const SizedBox(height: 14),
      SizedBox(height: 110,
        child: Row(crossAxisAlignment: CrossAxisAlignment.end,
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: List.generate(7, (i) {
          final h = exp[i] / maxVal * 80;
          final days = ['一', '二', '三', '四', '五', '六', '日'];
          return Column(children: [
            Text('${exp[i]}',
                style: const TextStyle(color: _primary,
                    fontSize: 11, fontWeight: FontWeight.w700)),
            const SizedBox(height: 4),
            Container(width: 14, height: h,
              decoration: BoxDecoration(
                gradient: const LinearGradient(
                  colors: [_primary, Color(0xFF4338CA)],
                  begin: Alignment.topCenter,
                  end: Alignment.bottomCenter),
                borderRadius: BorderRadius.circular(4)),
            ),
            const SizedBox(height: 6),
            Text(days[i],
                style: const TextStyle(color: _sub, fontSize: 11)),
          ]);
        })),
      ),
    ]),
  );
}

本周收支用 7 根柱子展示一周每日的收入和支出对比。柱子用双色编码——上方绿色为收入、下方红色为支出,形成「上下对称」的视觉,让用户一眼识别「净支出」状态。

从「本周收支柱状图」的财务流向可视化与消费习惯洞察设计角度再补一段。个人记账的核心价值是「让用户看到自己的财务流向」——单看支出金额没意义,必须放在「收入背景」下对比才能看出健康状况。这段双色柱状图把每天的收支同屏展示,绿色柱高于红色柱表示当日盈余,反之为亏损。如果连续 5 天支出大于收入,可以在卡片底部弹出"消费预警"chip。如果未来要扩展支持「分类细化」(每根柱子内部用色块表示不同分类的占比),可以接入鸿蒙 6.0 的 Skia 自绘做堆叠柱状图,性能足以支持每秒 60 帧重绘。
在这里插入图片描述

代码三:分类支出占比

Widget _category() {
  final items = const [
    ['餐饮', 0.38, _accent],
    ['交通', 0.18, _amber],
    ['购物', 0.22, _primary],
    ['娱乐', 0.10, _green],
    ['其他', 0.12, _sub],
  ];
  return Container(padding: const EdgeInsets.all(16),
    decoration: BoxDecoration(color: _card,
        borderRadius: BorderRadius.circular(16)),
    child: Column(crossAxisAlignment: CrossAxisAlignment.start,
        children: [
      const Text('支出分布',
          style: TextStyle(color: _ink, fontSize: 14,
              fontWeight: FontWeight.w700)),
      const SizedBox(height: 14),
      Row(children: items.map((it) {
        final ratio = it[1] as double;
        final c = it[2] as Color;
        return Expanded(flex: (ratio * 100).round(),
          child: Container(height: 14, color: c));
      }).toList()),
      const SizedBox(height: 12),
      Wrap(spacing: 14, runSpacing: 8,
          children: items.map((it) {
        final c = it[2] as Color;
        return Row(mainAxisSize: MainAxisSize.min, children: [
          Container(width: 10, height: 10,
            decoration: BoxDecoration(color: c,
                borderRadius: BorderRadius.circular(2))),
          const SizedBox(width: 6),
          Text('${it[0]} ${((it[1] as double) * 100).toInt()}%',
              style: const TextStyle(color: _ink, fontSize: 12)),
        ]);
      }).toList()),
    ]),
  );
}

分布数据可以做成桌面服务卡片让用户随时看到本月最大开支项,督促用户调整消费习惯。

从「分类支出占比」的消费洞察与可视化设计角度再补一段。个人记账类应用的核心洞察价值在于让用户看到「钱花在哪了」。这段卡片用横向条形图展示各分类支出占比——食物、交通、购物、娱乐、医疗、教育等。每个分类用对应主题色 + 数值 + 百分比的三件套呈现,让用户一眼识别「占比最大的是哪一项」。如果食物占比超过 40%(异常高),可以让该条变红色警示。如果未来要扩展支持「按分类查看明细」(点击某分类展开当月全部该类支出),可以用 ExpansionTile 实现折叠面板。鸿蒙 6.0 的 Skia 对横向进度条渲染极高效,配合 FormExtensionAbility 把「本月最大开支项」做成桌面卡片,让用户每天解锁就能反思消费。

心得

记账类 App 的视觉灵魂是"清爽 + 鼓励"——靛蓝色给清爽,“省了 ¥X” chip 给鼓励。开发时最容易犯的错是把记账界面做得过于复杂(分类二级、币种、汇率等),反而让用户嫌麻烦不想记。我的策略是把"记一笔"做成最大的按钮 + 语音输入辅助,让记账从 30 秒降到 3 秒。从能力扩展角度,记账应用最值得在鸿蒙端打造的是"HMS Wallet 自动同步 + AI 语音记账 + 桌面服务卡片"三件套。
在这里插入图片描述

总结

本篇实现了 Harmony 6.0 端的个人记账本首页,5 个模块、纯 UI、零依赖、约 360 行代码。从扩展角度建议生产业务里:把支付凭证接入 HMS Wallet 自动记账;把语音记账接入 AI 助手;把账本接入分布式数据;把"本月已花"做成 FormExtensionAbility 桌面卡片;把每日记账提醒接入 PushKit。下一篇是第十八组的最后一块——二手书交易应用。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐