一、实验题目

个人理财小助手

二、实验目的

  1. 掌握 SQLite 数据库及其使用。
  2. 熟练掌握布局及常用控件 Button、ListView、EditText、TextView 等。

三、总体设计

(含背景知识或基本原理与算法、或模块介绍、设计步骤等)

3.1背景知识

基于android的理财小助手app,开发采用了增量式软件开发模型。主要应用了listView、button、editText、textView、spinner、dialog、CalendarView、menu等Android原生控件,以及自定义View控件ShanView(扇形图)、CircleProgressBar(环形进度条);采用了分层式类似MVC的结构,分为Activity(View)、JavaBean(Model)、Service(Control),另外有Util包(工具类,包含字符串处理类、时间格式转换类、数据库操作类等)。以达到在模块层次上减小耦合、提高内聚的设计目标。

3.2 总体设计

3.3模块介绍

3.31登录注册模块

(1)登录模块:主要是用户登录功能的实现,具有填写用户名、密码、选择角色(用户/管理员)的表单。还有登录的跳转按钮。登录方面,密码填写为密码框,并附带一个图标按钮(isSelected实现)可以点击实现显示/隐藏密码。非初次登录,当用户填写完用户名后,会自动填写密码(sharedpreferences实现)。当用户名文本框焦点改变时,上方的圆形头像会自动旋转一周(animation实现)。涉及到数据库用户表的查询操作,语句为"select password from user where name =’" + name + “’”;页面图片为图1。
(2)注册模块:主要是用户注册功能的实现。Ui界面用的是登录模块的,具有判断用户是否已经被注册的功能。用户名和密码不为空。涉及到数据库用户表的查询插入操作。管理员方面,会自动创建一个管理员账号,sql语句为"insert into user (name,password,role) values (‘admin’,‘admin’,‘管理员’)";页面图片为图1。

3.32数据展示模块

(1)季节收入展示模块:利用circleprogressbar(环形进度条)实现分季节统计收入金额。共分春夏秋冬四个季节,春季(3、4、5月)、夏季(6、7、8月)、秋季(9、10、11月)、冬季(12、1、2月)。页面图片为图6。

(2)季节支出展示模块:与季节收入展示模块类似,利用circleprogressbar(环形进度条)实现分季节统计收入金额。共分春夏秋冬四个季节,春季(3、4、5月)、夏季(6、7、8月)、秋季(9、10、11月)、冬季(12、1、2月)。页面图片为5。

(3)本月收入展示模块:获取当前月份,分类(外快、兼职、工资、津贴)统计收入来源,使用自定义扇形图控件shanView,涉及到数据库的语句为"select sum(income.money) as money from income where name =’"+ LoginActivity.name +"’ and date like ‘%"+year+"-"+month+"-%’",思路是先分月求和查询,然后再求季节总和。页面图片为图11。

(4)本月支出展示模块:与本月收入展示模块类似,获取当前月份,分类(餐饮、交通、娱乐、购物)统计支出方向,使用自定义扇形图控件shanView,涉及到数据库的语句为"select sum(outcome.money) as money from outcome where name =’"+ LoginActivity.name +"’ and date like’%"+year+"-"+month+"-%’",思路也是先分月求和查询,然后再求季节总和。页面图片为图11。

3.33数据管理模块

便签管理模块:分两个页面,一个新增便签,一个查询便签。其中新增便签较为简单,查询便签是按照便签内容进行模糊查询。运用数据库查询语句关键字like。例如select * from tips where info like ‘%今天%’;通过检测文本框的内容是否发生变化,如发生变化,则执行一次模糊查询并把结果显示在下方的文本框中。页面图片为图10和图12。

收支管理模块:由新增收支记录、删除收支记录、统计收支(3.32 数据展示模块)、查询收支记录组成。新增收支比较简单,查询和删除写在了一起,具体实现思路是查询所有的记录,然后用lisetview展示,利用setOnItemClickListener()监听实现对行(记录)的选中,然后弹出一个对话框,可以选择是否删除此条记录。页面图片为图3。

具体代码如下

dialog = new AlertDialog.Builder(MyIncomeActivity.this).setTitle("系统提示").setMessage("是否删除此条记录?").setIcon(R.mipmap.ic_launcher).setPositiveButton("确定", new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {// 删除一条记录String sql = "delete from income where _id="+id_selected;System.out.println(sql);dbprocess2.execSql(sql);
Toast.makeText(MyIncomeActivity.this,"删除成功,请刷新页面查看",Toast.LENGTH_SHORT).show();}})
.setNegativeButton("取消",null).create();

数据导出模块:导出数据为txt文件,虽然有些过时,没有采取新功能比如发邮件的形式,但是也算是做了经典的文件存储功能的实现,巩固了基础。思路是查询所有记录,存入arraylist中(数组队列),然后在文件输出流中用getXX()方法取出来,存入文件。
具体实现代码如下

private void exportIncomeToTxt() {SQLiteDatabase db=helper.getWritableDatabase();String sql = "select * from income";Cursor cursor = db.rawQuery(sql, null);List<Income> list = new ArrayList<>();while(cursor.moveToNext()){Income income = new Income();income.set_id(cursor.getString(0));income.setMoney(cursor.getString(2));income.setDate(cursor.getString(3));income.setClasses(cursor.getString(4));income.setPayer(cursor.getString(5));income.setComment(cursor.getString(6));list.add(income);System.out.println((income.get_id()+","+income.getMoney()+","+income.getDate()+","+income.getClasses()+","+income.getPayer()+","+income.getComment()+"\r\n"));}cursor.close();db.close();StringBuffer buffer = new StringBuffer();buffer.append("id,金额,时间,类别,付款方,备注\r\n");for(Income income:list){buffer.append(income.get_id()+","+income.getMoney()+","+income.getDate()+","+income.getClasses()+","+income.getPayer()+","+income.getComment()+"\r\n");}String data = buffer.toString();String filename = "收入账单_"+CurrentTime.getCurrentTime()+".txt";FileOutputStream fos;try {fos = openFileOutput(filename,MODE_PRIVATE);fos.write(data.getBytes());fos.close();} catch (Exception e) {e.printStackTrace();}}

3.34系统设置模块

系统设置模块主要由修改密码、修改壁纸组成。都比较简单,这里就不一一赘述了。长话短说,修改壁纸主要是利用sharepreferences来存储当前壁纸,然后主菜单一调用onCreate()方法就会设置壁纸。

四、详细设计(含主要的数据结构、程序流程图、关键代码等)

4.1数据库设计

4.11实体设计:E-R图

实体类:用户、收入表、支出表、收支便签

4.12Sql语句:

CREATE TABLE income(_id integer primary key autoincrement,name varchar(20) not null,money varchar(20) not null,date varchar(20) not null,class varchar(20) not null,payer varchar(20) not null,comment varchar(50) not null);CREATE TABLE outcome(_id integer primary key autoincrement,name varchar(20) not null,money varchar(20) not null,date varchar(20) not null,class varchar(20) not null,location varchar(20) not null,comment varchar(50) not null);CREATE TABLE tips(_id integer primary key autoincrement,name varchar(20) not null,info varchar(50) not null);CREATE TABLE user(name varchar(20) primary key not null,password varchar(20) not null,role varchar(20) not null);

4.2活动图设计

4.3用例图设计

4.4关键代码

4.41数据库部分:

package com.example.myapplication5.Utils;
/* 本来想定义为静态工具类的,由于有传入参数helper,故不这样设置 */
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;import static java.lang.Integer.parseInt;public class dbProcess2 {//    启动类private MyHelper helper;//    数据库private SQLiteDatabase db;public dbProcess2(MyHelper helper) {this.helper = helper;}//    每次的数据库对象要重新获取
//    增删改public void execSql(String sql) {//  获取数据库db = helper.getWritableDatabase();db.execSQL(sql);db.close();}//    查询收支记录public void query(String sql, TextView mTvShow, Context context) {//  获取数据库db = helper.getWritableDatabase();Cursor cursor = db.rawQuery(sql, null);int number = cursor.getCount();if (cursor.getCount() == 0) {mTvShow.setText("");Toast.makeText(context, "没有数据", Toast.LENGTH_SHORT).show();} else {cursor.moveToFirst();
//            下标从0开始mTvShow.append("\n------------------------------");mTvShow.setText("\n" + cursor.getString(2) + "元," + cursor.getString(3) + "," + cursor.getString(4) + "," + cursor.getString(5) + "," + cursor.getString(6));mTvShow.append("\n------------------------------");}while (cursor.moveToNext()) {mTvShow.append("\n" + cursor.getString(2) + "元," + cursor.getString(3) + "," + cursor.getString(4) + "," + cursor.getString(5) + "," + cursor.getString(6) );mTvShow.append("\n------------------------------");}cursor.close();db.close();}//    查询收支便签public void queryTips(String sql, TextView mTvShow, Context context) {//  获取数据库db = helper.getWritableDatabase();Cursor cursor = db.rawQuery(sql, null);int number = cursor.getCount();System.out.println(number+"------");if (cursor.getCount() == 0) {mTvShow.setText("");System.out.println(1111);Toast.makeText(context, "没有数据", Toast.LENGTH_SHORT).show();} else {Toast.makeText(context,"查询到"+number+"条数据",Toast.LENGTH_SHORT).show();cursor.moveToFirst();
//            下标从0开始
//            setText-->appendSystem.out.println(cursor.getString(0)+cursor.getString(2));mTvShow.setText(cursor.getString(0) + "," + cursor.getString(2) + ";");}while (cursor.moveToNext()) {System.out.println(cursor.getString(0)+cursor.getString(2));mTvShow.append("\n" + cursor.getString(0) + "," + cursor.getString(2) + ";");}cursor.close();db.close();}//  根据用户名查询密码或权限public String queryOne(String sql) {//  获取数据库db = helper.getWritableDatabase();Cursor cursor = db.rawQuery(sql, null);if (cursor.getCount() == 0) {return "用户不存在";} else {cursor.moveToFirst();/* 这里index为何是0 解答:因为这里获取的是单个列---select password/role */return cursor.getString(0);}}//    根据用户名查询收入/支出表 根据月份查询收支表public int queryMoney(String sql) {int count = 0;//  获取数据库db = helper.getWritableDatabase();Cursor cursor = db.rawQuery(sql, null);System.out.println("查询到的记录条数"+cursor.getCount());if (cursor.getCount() == 0) {return 0;} else {cursor.moveToFirst();String num = cursor.getString(0);if (StringUtils.isBlank(num)){//                这里需要加个判断是否为空,为啥总会查到一条记录 ???return 0;}count = parseInt(num);System.out.println("-----" + num + "-----");}cursor.close();db.close();return count;}}

4.5 运行效果截图


图1 登录注册

图2 后台管理页

图3 我的收入页

图4 数据管理页


图5-6 数据可视化页面

图7 主菜单界面

图8 新增收入页

图9 系统设置页

图10 新增便签页

图11 本月收入/支出

图12 查询便签

五、实验结果与分析

本次课程设计实现了登录注册、新增收入、新增支出、查询所有收入、查询所有支出、按id删除收入记录、按id删除支出记录、统计当年季节收入金额及比例并展示、统计当年季节支出金额及比例并展示、统计当月收入来源、统计当月支出去向(扇形图)、更换壁纸、更改密码、数据导出(txt文件)新增收支便签、查询收支便签(按内容进行模糊查询like)等功能。总体上达到了指导书上的设计要求。并有些许创新,比如在控件的使用上选择了更多没接触过的控件,如在收支记录的时间选择上使用了CalendarView、在收支类别上选择了Spinner、在数据管理页功能选择上使用了menu、在季节收支比例上使用了自定义环形进度条,并加入了动态绘图功能,丰富了用户体验。还有学习借鉴了csdn上大佬的自定义扇形图控件。

六、小结与心得体会

本次课程设计历时两周,感受颇多,收获颇多。可以算是自己独立设计的比较成熟的第一个项目吧,应用了数据库技术、mvc架构思想、分层分级思想、android界面设计、组件设计。这个项目代码量比较大,有三十多个类,所以代码冗余也是一大缺点,有些功能函数其实可以分离出去单独成一个类,但是分离之后的接口设计层次我又有点不知所措。比如自己封装好的数据库操作类dbprocess2.class,在增删改查上实现了通用的功能,但是在某些页面上查询展示需要个性化需求,又不得不重写一个类似的方法,不然为了通用又得改原方法。这个涉及到个人在内聚耦合的选择。我尽量去做到“低耦合,高内聚”
       代码设计中我尽量秉持着规范化原则,每个模块都写了注释,不仅方便别人看懂,也能然自己思路清晰,方便查找修改bug。在设计中我也使用了测试类junit,这样尤其对于android这样需要页面驱动的方法调用比较好单独测试一个模块一个函数的功能,经测试后再加入原程序。
       在题目选择方面,相比ui设计,我更注重业务逻辑,所以选择了界面较为简单的理财小助手。其他题目的ui设计较为复杂,再去开发完整会比较耗时。但也会适当加入美化页面的新控件,以使自己在熟练掌握已学知识的基础上进行拓展。立足基础,增量式设计。
       本次课程设计由自己独立完成,做出成品的那一刻觉得所有辛苦都值得了,满满的成就感,每个作品就像自己的孩子一样,都记录着自己成长的足迹。
       也感谢老师在最后的验收环节给予我的意见和建议以及肯定,我会尽量去改正。比如流程图的设计上我会更加规范化,采用工程化的uml设计,规范自己。尽量养成好的习惯,这次课程设计的过程中我做了大量的记录工作,每天都有简洁的写日志和总结自己遇到的问题,然后多思考大体确定第二天的设计目标,要加哪些模块等等。在这样也使我目标明确,有方向感。在敲代码的过程中,并不显得轻松,但我还算比较有韧性,遇到难题不轻易放弃,尽量去学习别人的经验,搜索了大量的博客,有些人写的比较好我采纳了。这样才使得最后能够做出来。

基于Android原生开发的理财小助手APP相关推荐

  1. 【Android原生开发】个人小助手

    一. 项目开发的背景 用于安卓手机的个人日常管理系统的设计与开发,实现个人收支管理.日程管理.闹钟提醒.日程数据库的添删改查等功能,系统使用SQLite数据库实现了日程记录数据的管理,挥SQLite占 ...

  2. 湖南科技大学Android课程设计之个人理财小助手APP

    本文目录 项目介绍 目录结构 总体设计 效果展示 项目总结 后续!!! 项目介绍 基于android原生开发的的理财小助手app,开发采用了增量式软件开发模型,采用轻量级数据库SQLite存储.主要应 ...

  3. Android课设——理财小助手

    一:app介绍 理财小助手是一款利用Android studio软件实现的APP,可以录入每天的消费项目以及消费金额,同时也可以查找消费记录.统计消费总额.我用到的Android studio版本如下 ...

  4. (超多图)基于Android studio开发的一个简单入门小应用(超级详细!!)(建议收藏)

    基于Android studio开发的一个简单入门小应用 一.前言 二.前期准备 三.开发一个小应用 五.运行应用 一.前言 在暑假期间,我学习JAVA基础,为了能早日实现自己用代码写出一个app的& ...

  5. 基于Android平台的疫情小助手APP

    1.选题背景和意义 新型冠状病毒感染的肺炎疫情给人们的身心和生活带来了不利的影响.面对病魔,全国上下团结一心,同舟共济,共同战"疫".疫情小助手APP可以为大家的生活带来便利.疫情 ...

  6. 在VC中使用ADO开发一款家庭理财小助手软件

    家庭理财小助手(绿色小软件): 此软件可以实现四个功能:1.对家庭月状况进行统计,并可查询之前某月的财务情况,如需查询2010年10月,可输入:201010,点击查询即可:2.对家庭年状况进行统计,如 ...

  7. Kotlin 风险高、RxJava 已过时,Android 原生开发现状分析!

    当你好不容易学会了某个框架或者工具,觉得它很好用的时候,它或许就要过时了. 英文:The State of Native Android Development 作者:Vasiliy Zukanov, ...

  8. android收入管理系统,毕业设计(论文)-基于Android系统的家庭理财通软件的设计——收入管理模块.docx...

    PAGE 河北农业大学信息学院 本科毕业论文 题 目:基于Android系统的家庭理财通软件的 设计--收入管理模块 学 院: 信息科学与技术学院 专业班级: 计算机科学与技术0902班 学 号: 二 ...

  9. AndroidStudio_下载和安装---Android原生开发工作笔记67

    以前写的那个教程到66,是用eclipse,安装插件来开发Android原生程序的,那个已经是,8年前才那么做的, 现在公司让做Android原生开发...再来学一学,这个新的AndroidStudi ...

最新文章

  1. 哈尔滨阳光计算机学院是不是黄了,黑龙江这4所野鸡大学,常被误认为是名校,实则害人不浅...
  2. 扒一扒TCP协议与UDP协议
  3. Linux下的用户、组和权限的详细解释
  4. extract-text-webpack-plugin用法
  5. ext.net 开发学习之TabPanel (二)
  6. @Zabbix配置snmptrap及使用snmptt解析格式化输出
  7. 学校计算机考证要交费吗,大家好,请问技校考证要交几百元费用是否可以?
  8. 景深 (摄影测量与遥感学术语)
  9. 第一行输入一个正整数N,随后的N行各输入一个人的姓名和年龄,中间用空格分隔(形如 “Tom 18“),将字符串转为形如 {“name“:“Tom“,“age“:18} 的字典,按顺序加入到列表中,得到
  10. html5怎么给视频加字幕,2018版本的pr如何给视频加字幕?
  11. numpy部分函数使用总结
  12. 混合柯西变异和均匀分布的蝗虫优化算法-附代码
  13. 美国宾州计算机学校,不输加州!美国这个州的名校远比你想象的多
  14. 【随问】网址中的www是什么意思?HTTPS和HTTP的区别是什么?
  15. 邮箱地址注册申请能免费注册吗?
  16. QQ邮箱的一些bug
  17. 一只喵的西行记-8 魔法猫堡
  18. 拼多多关键词搜索商品详情分析接口(分类ID搜索精准商品数据)代码对接教程
  19. 轻量化后台管理HTML设计页面
  20. 单个页面多个按钮调用同一个弹窗,和滚屏展示效果,关闭后,5秒自动弹出滚屏展示!

热门文章

  1. 定期沟通及反馈的必要性
  2. 人工智能导论实验——基于MindSpore的广告推荐
  3. 内网渗透系列:信息搜集方法小结2
  4. juniper 认证学习、报名地址汇总
  5. 2017年第23届中国东北国际建筑装饰博览会会刊(参展商名录)
  6. Salesforce自定义搜索结果布局
  7. html5视频前端视频上传,手机拍照上传,手机录像上传
  8. 一、对C语言的初步认识
  9. 大数据面试重点之kafka(六)
  10. 关于ps cs5的一些问题