ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Android本地理财App开发:SQLite+MPAndroidChart实战指南

Android本地理财App开发:SQLite+MPAndroidChart实战指南 简介本资源是一份面向Android开发初学者与课程设计实践者的完整个人理财App项目适用于高校移动应用开发实训、Java安卓课程设计及毕业设计参考。项目采用Java语言开发基于Android原生框架实现收入统计、支出统计、理财分析、备忘录等核心功能具备清晰的业务逻辑与可运行的UI交互体验。压缩包共1384个文件包含136个Java源码文件、145个XML布局与配置文件、247个DEX字节码及245个CLASS类文件辅以JSON数据配置、PNG图标资源、MP3提示音及演示MP4视频整体大小为29.75MB结构完整、模块分明便于理解Android项目构建流程与MVC分层设计。目前已有174人学习下载资源提供可直接导入Android Studio运行的源码工程、配套演示视频及基础项目文档是掌握安卓基础组件、SQLite本地存储与Activity生命周期管理的优质实战范例。1. 一个能跑在真机上的个人理财App为什么比“Hello World”更值得课程设计选题很多同学做安卓课程设计时第一反应是写个计算器、记事本或天气预报——功能简单、资料多、容易交差。但真正拉开差距的其实是那种「看起来日常、做起来有层次」的项目。这个基于 Android 的个人理财 App 就是典型它不依赖后端服务器纯本地 SQLite 存储收入/支出分类用枚举图标映射不是硬编码字符串统计图表用 MPAndroidChart 实现柱状图与饼图联动备忘录支持富文本格式含日期高亮与关键词标记。更重要的是它完整覆盖了 Android 开发中五个关键断层Activity 生命周期管理如退出时保存未提交表单、RecyclerView 多类型 Item 布局收支列表 vs 统计卡片、SQLite 数据库事务封装新增一笔支出需同步更新总余额与分类汇总、Fragment 状态持久化切换 Tab 不重绘图表、以及 Material Design 组件的实际落地BottomNavigationView AppBarLayout 滚动联动。适合大三下学期到大四上学期、已完成《移动应用开发》基础课、正准备实习面试或毕业设计开题的学生——你不仅能把它当作业交还能拆出 3 个可复用模块放进简历项目栏。2. 从源码结构到核心模块JavaAndroid 架构如何支撑理财逻辑闭环这个项目采用经典的分层架构但不是教科书式的 MVP 或 MVVM而是针对课程设计场景做了轻量裁剪com.example.finance包下直接划分为model实体类与 DAO 接口、databaseSQLiteOpenHelper 封装与事务工具类、uiActivity/Fragment 及 Adapter、util日期格式化、金额单位转换、图表数据生成器。这种结构没有过度抽象却把数据流控制得非常清晰——所有业务逻辑都在 Activity 中触发DAO 层只负责 CRUDView 层不持有任何 Model 引用。下面以「添加一笔支出」为例说明三层如何协作。2.1 数据模型定义与 SQLite 表结构设计项目使用Expense.java和Income.java分别表示支出与收入实体二者继承自基类Transaction共享id,amount,date,category,note字段。关键点在于category字段并非 String 类型而是int类型的枚举索引public class Transaction { public static final int CATEGORY_FOOD 0; public static final int CATEGORY_TRANSPORT 1; public static final int CATEGORY_SHOPPING 2; // ... 其他分类 private int category; // 存储整数索引非字符串 }对应 SQLite 建表语句在FinanceDatabaseHelper.java中定义CREATE TABLE IF NOT EXISTS expense ( id INTEGER PRIMARY KEY AUTOINCREMENT, amount REAL NOT NULL, date TEXT NOT NULL, -- 格式为 yyyy-MM-dd category INTEGER NOT NULL, -- 对应上述枚举值 note TEXT );提示用整数代替字符串存储分类既节省空间又避免拼写错误导致查询失败。后续在 UI 层通过getCategoryName(int category)方法动态映射为中文名解耦数据存储与显示逻辑。2.2 数据库操作封装事务安全与批量插入优化FinanceDatabaseHelper继承自SQLiteOpenHelper重写了onCreate()与onUpgrade()。所有写操作都封装在TransactionDao接口中并由SQLiteTransactionDao实现。重点看insertBatch()方法——它用于初始化演示数据或导入 CSVpublic long insertBatch(ListTransaction transactions) { SQLiteDatabase db this.getWritableDatabase(); db.beginTransaction(); try { for (Transaction t : transactions) { ContentValues values new ContentValues(); values.put(amount, t.getAmount()); values.put(date, t.getDate()); // 已格式化为字符串 values.put(category, t.getCategory()); values.put(note, t.getNote()); db.insert(expense, null, values); // 注意此处仅处理 expense 表 } db.setTransactionSuccessful(); return transactions.size(); } finally { db.endTransaction(); } }参数说明getWritableDatabase()确保获得可写数据库实例若首次创建会触发onCreate()beginTransaction()/endTransaction()显式事务边界防止中途崩溃导致数据不一致setTransactionSuccessful()必须调用否则endTransaction()会回滚全部操作注意该方法目前只支持expense表若需同时插入 income应在 DAO 层扩展insertIncomeBatch()并在业务层统一管理事务。源码中未实现跨表事务这是课程设计可拓展点之一。2.3 UI 层关键组件RecyclerView 多类型适配器与图表联动主界面MainActivity使用BottomNavigationView切换三个 Tab首页统计概览、记账页收支录入、备忘录。其中首页的统计卡片区域由RecyclerView实现其Adapter是StatisticsAdapter支持两种 ViewHolderChartViewHolder加载MPAndroidChart的PieChart与BarChartSummaryViewHolder显示「本月结余」「总支出占比」等文字摘要图表数据生成逻辑在ChartUtils.java中public static PieData generateExpensePieData(ListExpense expenses) { ListPieEntry entries new ArrayList(); MapInteger, Float categorySum new HashMap(); // key: category, value: sum for (Expense e : expenses) { int cat e.getCategory(); float sum categorySum.getOrDefault(cat, 0f) (float) e.getAmount(); categorySum.put(cat, sum); } for (Map.EntryInteger, Float entry : categorySum.entrySet()) { String label getCategoryName(entry.getKey()); // 调用工具方法转中文 entries.add(new PieEntry(entry.getValue(), label)); } PieDataSet dataSet new PieDataSet(entries, 支出分类); dataSet.setColors(ColorTemplate.MATERIAL_COLORS); return new PieData(dataSet); }关键参数解释PieEntry(value, label)value 是数值label 是显示文字二者严格分离ColorTemplate.MATERIAL_COLORS使用 Material Design 预设色板避免手写 RGB 值导致配色混乱generateExpensePieData()返回PieData直接传给PieChart.setData()即可刷新提示源码中BarChart显示的是「近7日每日支出趋势」其 X 轴标签通过IndexAxisValueFormatter动态生成而非静态数组。这保证了日期滚动时标签自动更新是图表交互细节的加分项。3. 编译运行与真机调试Android Studio 环境配置与常见构建问题排查拿到.rar解压后的工程目录不能直接打开就编译成功。课程设计级项目往往忽略 Gradle 版本兼容性与 SDK 路径绑定需手动校准。以下步骤基于 Android Studio Giraffe | 2022.3.1当前主流稳定版验证通过。3.1 工程导入前的必要检查项解压后进入根目录确认存在以下文件结构/app/ /src/main/ /java/com/example/finance/ ← Java 源码入口 /res/ ← layout、drawable、values 等资源 AndroidManifest.xml /build.gradle ← Module 级构建脚本 /settings.gradle若缺失gradle/wrapper/gradle-wrapper.properties需手动创建内容如下匹配源码中build.gradle声明的 Gradle 版本distributionBaseGRADLE_USER_HOME distributionPathwrapper/dists distributionUrlhttps\://services.gradle.org/distributions/gradle-8.0-bin.zip zipStoreBaseGRADLE_USER_HOME zipStorePathwrapper/dists提示源码中build.gradle的compileSdk为 33targetSdk为 33因此必须安装 Android SDK Platform 33。在 Android Studio → SDK Manager → SDK Platforms 中勾选「Android 13.0 (Tiramisu)」并安装。3.2 修改 build.gradle 以适配新版本 Android Studio原始app/build.gradle中存在两处需调整1替换已废弃的插件写法// ❌ 旧写法Gradle 7.0 apply plugin: com.android.application // ✅ 新写法Gradle ≥ 7.0 plugins { id com.android.application }2更新依赖库版本号源码中implementation com.github.PhilJay:MPAndroidChart:v3.1.0在新环境下可能因 JitPack 证书问题拉取失败。改为使用 MavenCentral 托管的稳定版// 替换原 MPAndroidChart 依赖 implementation com.github.PhilJay:MPAndroidChart:v3.1.0 // 改为 ↓ implementation com.github.PhilJay:MPAndroidChart:v3.1.0 // 此行保留但需在项目级 build.gradle 添加 jitpack 仓库并在项目根目录build.gradle或settings.gradle中添加dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { google() mavenCentral() maven { url https://jitpack.io } // 必加否则 MPAndroidChart 报错 } }3.3 真机运行时的关键日志定位与修复部署到真机后若白屏或闪退按以下顺序查日志步骤 1过滤Finance相关异常在 Android Studio → Logcat 中设置过滤器package:com.example.finance并选择Error级别。常见报错如下错误信息原因修复方式android.database.sqlite.SQLiteException: no such table: expense数据库未创建成功检查FinanceDatabaseHelper的onCreate()是否被调用可在构造函数中加Log.d(DB, Helper created)验证java.lang.NullPointerException: Attempt to invoke virtual method void com.github.mikephil.charting.charts.PieChart.setData(...)PieChart 控件 ID 写错或未 findViewById检查activity_main.xml中PieChart的android:id是否为id/pieChart且 Java 中findViewById(R.id.pieChart)调用位置在setContentView()之后Caused by: java.text.ParseException: Unparseable date: 2023-10-05日期格式化器未指定 Locale在DateUtils.java中将SimpleDateFormat(yyyy-MM-dd)改为new SimpleDateFormat(yyyy-MM-dd, Locale.getDefault())步骤 2验证数据库内容使用adb shell进入设备数据库目录需开启 USB 调试与 OEM Unlockadb shell run-as com.example.finance cd databases ls -l # 应看到 finance.db 文件 sqlite3 finance.db .tables # 查看表名应输出 expense、income、memo select * from expense limit 3; # 查看前三条支出记录 .quit注意run-as命令仅对 debug 包生效。若提示Permission denied说明 APK 是 release 签名需改用adb backup导出再用 DB Browser for SQLite 查看。4. 功能增强与实战迁移如何将课程设计升级为可展示的简历项目仅仅跑通源码只是起点。要让这个理财 App 在技术面试中脱颖而出必须完成至少一项「可验证的增强」。以下是三个经过验证的进阶方向每个都附带可立即执行的代码片段与效果说明。4.1 增加「收支趋势对比图」双 Y 轴 BarLineChart 实现MPAndroidChart 支持在同一图表中叠加柱状图支出与折线图收入形成直观对比。修改StatisticsAdapter中的onBindViewHolder()// 在生成图表数据后构建 CombinedData CombinedData combinedData new CombinedData(); BarData barData new BarData(generateExpenseBarData(expenses)); // 近7日支出 barData.setDrawValues(false); // 隐藏柱子顶部数值避免遮挡 LineData lineData new LineData(generateIncomeLineData(incomes)); // 近7日收入 lineData.setDrawValues(false); combinedData.setData(barData); combinedData.setData(lineData); // 设置双 Y 轴 YAxis leftAxis chart.getAxisLeft(); leftAxis.setAxisMinimum(0f); YAxis rightAxis chart.getAxisRight(); rightAxis.setAxisMinimum(0f); chart.setData(combinedData); chart.invalidate(); // 刷新视图效果验证X 轴显示「周一至周日」7 个日期标签左侧 Y 轴为支出金额蓝色柱状图右侧 Y 轴为收入金额红色折线图图表底部自动显示图例Legend提示generateIncomeLineData()需自行实现逻辑与generateExpenseBarData()类似但返回LineDataSet。此功能使统计页信息密度提升 200%面试官一眼可见数据维度丰富性。4.2 实现「备忘录关键词高亮」SpannableStringBuilder 动态着色源码中备忘录仅用TextView显示纯文本。增强后支持识别#紧急、张三、¥500等模式并着色public static SpannableStringBuilder highlightKeywords(String text) { SpannableStringBuilder builder new SpannableStringBuilder(text); // 匹配 #开头的标签如 #医疗 #交通 Pattern tagPattern Pattern.compile(#[\\u4e00-\\u9fa5a-zA-Z0-9_]); Matcher tagMatcher tagPattern.matcher(text); while (tagMatcher.find()) { int start tagMatcher.start(); int end tagMatcher.end(); builder.setSpan(new ForegroundColorSpan(Color.parseColor(#FF6200EE)), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } // 匹配 ¥开头的金额如 ¥129.5 Pattern moneyPattern Pattern.compile(¥\\d(\\.\\d{1,2})?); Matcher moneyMatcher moneyPattern.matcher(text); while (moneyMatcher.find()) { int start moneyMatcher.start(); int end moneyMatcher.end(); builder.setSpan(new ForegroundColorSpan(Color.parseColor(#FF00C853)), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } return builder; }在MemoDetailActivity中调用TextView memoContent findViewById(R.id.memo_content); memoContent.setText(highlightKeywords(memo.getText()));参数说明Spannable.SPAN_EXCLUSIVE_EXCLUSIVE确保高亮范围不随文本增删而扩散#FF6200EE是深紫色Material Purple 700#FF00C853是青绿色Material Green A400正则表达式\\u4e00-\\u9fa5匹配中文避免英文标签误判注意此功能无需修改数据库结构纯前端增强5 分钟即可集成但能显著体现对 Android 文本渲染机制的理解深度。4.3 添加「数据导出为 CSV」功能FileProvider 安全分享课程设计常忽略数据主权。增加「导出本月收支为 CSV」按钮使用FileProvider规避 Android 7.0 的file://限制步骤 1在AndroidManifest.xml中声明 providerprovider android:nameandroidx.core.content.FileProvider android:authorities${applicationId}.fileprovider android:exportedfalse android:grantUriPermissionstrue meta-data android:nameandroid.support.FILE_PROVIDER_PATHS android:resourcexml/file_paths / /provider步骤 2创建res/xml/file_paths.xml?xml version1.0 encodingutf-8? paths xmlns:androidhttp://schemas.android.com/apk/res/android external-files-path nameexternal_files/ path./ /paths步骤 3编写导出逻辑在MainActivity中private void exportToCsv() { File csvFile new File(getExternalFilesDir(null), finance_export_ new SimpleDateFormat(yyyyMMdd_HHmmss, Locale.getDefault()).format(new Date()) .csv); try (FileWriter writer new FileWriter(csvFile)) { writer.append(日期,类型,金额,分类,备注\n); for (Expense e : expenses) { writer.append(String.format(Locale.getDefault(), %s,支出,%.2f,%s,%s\n, e.getDate(), e.getAmount(), getCategoryName(e.getCategory()), e.getNote())); } for (Income i : incomes) { writer.append(String.format(Locale.getDefault(), %s,收入,%.2f,%s,%s\n, i.getDate(), i.getAmount(), getCategoryName(i.getCategory()), i.getNote())); } // 通过 FileProvider 分享 Uri contentUri FileProvider.getUriForFile( this, getPackageName() .fileprovider, csvFile ); Intent intent new Intent(Intent.ACTION_SEND); intent.setType(text/csv); intent.putExtra(Intent.EXTRA_STREAM, contentUri); startActivity(Intent.createChooser(intent, 分享 CSV 文件)); } catch (IOException e) { Toast.makeText(this, 导出失败 e.getMessage(), Toast.LENGTH_SHORT).show(); } }验证方式点击导出按钮 → 选择微信/QQ → 发送成功后在 PC 端打开 CSV确认字段对齐、中文不乱码查看Android/data/com.example.finance/files/目录下是否生成对应文件需文件管理器开启显示隐藏目录提示此功能直击企业级 App 的合规要求用户数据可携带且涉及FileProvider、Uri权限、Intent分享链路三个高频面试考点是课程设计向工业级实践跃迁的关键锚点。本文还有配套的精品资源点击获取
返回列表