功能分析
记账 APP 需要有如下三个系统: 统计系统、记账系统、用户系统。
- 统计系统需要实现当月消费统计,包括收入、支出、结余等内容, 并可以让用户通过可视化图的方式清晰了解使用情况。
- 记账系统需要实现记账的操作,包括选择账 目类别、消费类型、金额、具体内容等,还需要有用户交互的过程,包括删除、修改、查询账目的 功能。
- 用户系统需要实现用户信息的提取,使用 APP 的帮助界面,用户资产管理,包括用户账户余 额可视化查看,用户账户管理,账户余额修改,并与记账系统交互,根据账目的修改和添加,实时进行反馈更新。
Activity 设计
MainActivity 设计
MainActivity 包含侧滑栏 SlidingPaneLayout,tabLayout 顶部标签以及 3 个 Fragment:账目 明细,月支出分类,资产管理。
- 侧滑栏 SlidingPaneLayout 主要实现侧滑菜单栏的效果,用于用户系统。左滑出现该用户界 面,包含用户的头像,介绍,账户,帮助,主题,退出的功能栏。为了便于用户查看,可从主 界面中通过左滑或者点击标题栏左侧的图标完成出现侧滑栏功能。为了用户视觉上的体验,本 侧滑栏带有缩放的效果,并不会完全覆盖主页面。为了使布局更美观用户界面功能有对应的图 标,且用户界面颜色与主界面的颜色系列保持一致。
- tabLayout 顶部标签包括账目明细,月支出分类,资产管理三个标签,分别对应三个 Fragment, 点击选择不同标签会出现不同 Fragment。
- 账目明细 Fragment 内包含当月的收入、支出、结余,以及账目明细的列表。该页面底部还含 有 4 个按钮,左一是选择日期查看该日的账目,左二是取消日期选择,左三为显示所有历史账目, 右一是添加账目,每条账目还可右滑进行修改和删除操作。
- 月支出分类 Fragment 显示当月支出不 同类型的金额饼状图,并会随账目明细的改变而改变。
- 资产管理 Fragment 显示虚拟账户、现金、 银行账户三种账户的资产情况,并用饼状图显示,同时配置修改按钮,修改资产情况。该 Fragment 会随账目明细的改变而改变。
EditActivity 设计
EditActivity 用于添加以及编辑账目,包括分类导航栏、类型选择、时间选择、输入账目名称、 金额、账户。
分类导航栏中含有 16 种账目类型可滑动翻页查看,类型包括收入和支出,只能二选其一。 账目名称和金额有输入框,点击账目类型会自动填充账目名称,也用户可以做更改,自动填入可以使用户的操作更简单,并在点击选择账目类型时底部弹出提示框。账户的选择由滚动选择器实 现。选择之后按钮文字会变成账户名称,便于用户查看。时间设有修改按钮,点击修改按钮会出现日历选择时间,选择后会实时更新日期。
数据结构设计
- 账户数据:账户数据是 Account 类,包括账户名称和账户余额,该类包含构造函数,以及所有成员变量的设置和读取方法。 设置 AccountData 类存放账户数据,包括数据文件名称 AccountData,上下文 Context,以 Account 类为元素的列表 AccountList。该类包含构造函数,保存数据 savaData 方法,加载数据 loadData 方法。
- 账目数据:账目数据是 Money 类,包括账目名称,账目金额,类型图片 ID,日期,收支类型,使用账 户六个成员变量。该类包含构造函数,以及所有成员变量的设置和读取方法。设置 DataBank 类存放账目数据,包括数据文件名称 data,上下文 Context,以 Money 类为 元素的列表,MoneyList。该类包含构造函数,保存数据 savaData 方法,加载数据 loadData 方法。
- 分类汇总数据:分类汇总数据是 Classify_ItemInfo 类,包括类型名称,分类 ID,金额 3 个成员变量。该类包含构造函数,以及所有成员变量的设置和读取方法。
相关实现技术
数据储存
用户资产和账目都需要储存。本项目运用内部储存的方法。
设备中每一个安装的 App,系 统都会在内部存储空间的 data/data 目录下以应用包名为名字自动创建与之对应的文件夹。本 APP 用 data 文件储存账目,Accoundata 文件储存资产信息。使用类将数据操作封装。
利用对象输出流和输入流,为应用提供对象持久化的功能,分别调用文件输出流和文件输入流来实现。
- 加载数据用对象输入流 ObjectInputStream,确保每次从流中读取的对象能匹配 Java 虚拟机中已经存在的类,读取存放在数据区的文件使用 openFileInput。利用对象输入流的方法 Object readObject(),从流中读取一个对象数据,赋值给类的列表成员变量。完成读取。
- 保存数据用对象输出流 ObjectOutputStream,将对象数据写入到文件。因为只有支持 Serializable 接口的对象支持写入到流,每个序列化对象被编码,所以需要将单条数据类 Account 和 Money 支持 Serializable 接口,即 class XXX implements Serializable{……}。写入存放在数据 区的文件使用 openFileOutput。利用对象输出流的方法 writeObject(Object obj),将一个对象,此处为列表,写入到流中。
用户菜单侧滑栏
本 APP 实现侧滑用户菜单栏的效果,主要利用 SlidingPaneLayout,该组件提供了一个水平的、多窗格的布局。其布局文件下面的第一个子控件是作为一个导航视图(滑动后左边视图),其余部分是内容视图。
- 新建一个视图类 CusSlidingPaneLayout 继承 SlidingPaneLayout。在 activity_main.xml 中把所有布局内容放入 CusSlidingPaneLayout 类的布局中,并将第一个 Layout 设置成用户菜单栏界面效果。
- 在 MainActivity 中的 MyFragmentAdpater 建立方法 initSlidingPaneLayout(),实现左侧栏滑动时有一个缩放的效果。
- onPanelSlide 方法滑动窗格的位置更改时调用,设置侧面栏缩放 setPivotX/Y、setScaleX/Y,设置首页滑动时缩放 setScaleX/Y、setElevation。在 onPaneSlide 中有两个参数,第一个参数是被移动的 view,第二个参数则是滑动时的偏移值,范围是 0~1。
- 对一 个 View 设置缩放动画时,缩放轴点默认是该 View 的中心点。改变缩放轴点位置需要通过 setPivotX/Y (float pivotX/Y)设置缩放轴点的坐标。再通过 setScaleX/Y 来实现最终的缩放效果。
- 实现直接通过点击一个按钮来打开左边栏,这时需要自定义方法 forbidSlide(boolean isForbid)禁止 SlidingPaneLayout 滑动。响应按钮 mSlidingPaneLayout.openPane();出现用户界面。
绘制饼状图
本 APP 使用 PieChart 组件绘制饼状图。
- 在 Fragment 的 xml 文件中添加 PieChart 控件,将 控件的形成封装在方法 Cteatechart()中,获取数据封装在方法 initData_classify()和 initData_out() 中。
- 不同分类的总金额需要借用另一个类 Classify_ItemInfo,利用方法 initData_classify()初始化类,获取所有的分类名称和 ID,加入一个列表中。
- initData_out()方法用于遍历账目,选择本月相应分类的账目金额累加进 Classify_ItemInfo 类相应 ID 的金额中。完成数据获取。
- 绘制饼状图,新建一个 List列表,存放处理好的数据,只加入不等于 0 的数据, 设 置 颜 色 列 表 用 于 表 示 不 同 分 类 , PieDataSet 、 PieData 结 合 起 来 用 于 存 放 数 据 ,pc.setData(pieData);设置饼图数据。数据设置完成。
- 完善饼图的视觉效果,更改字体颜色,饼图变为空心圆,放入标题字体(setCenterText),设 置连接线描述分类及具体金额,更改饼图大小(setExtraOffsets),完善布局,调用 Legend 类型的各 种方法设置图例(getLegend)。
RadioButton 单选
RadioButton 与 RadioGroup 结合使用,实现在多项中选取单项。
在布局文件中加入 RadioGroup 布局,在该布局下放两个 RadioButton。
在 EditActivity 中获取两个按钮,设置监听, 点击的时候将变量的值赋值为 0 或 1,用于后面判断当前选择的是收入还是支出。
Item 侧滑修改删除
利用封装好的组件 SwipeDelMenuLayout 实现侧滑,出现两个 Button 分别为修改和删除, 并响应它们的点击事件。
- 需要添加 JitPack 仓库依赖,以及依赖库 SwipeDelMenuLayout。
- 在账目列表的 item 中使用 SwipeDelMenuLayout 布局,将 item 的内容打包成一个布局放入该布局中, 并添加两个按钮。
- 在适配器MoneyListAdapter中MyViewHolder里添加获取SwipeDelMenuLayout 布局,并响应两个 Button,添加和删除。
- 用列表方法 remove 响应删除,并用 savaData 保存数据到数据文件,并调用函数更新显示列表。
- 在点击删除后创建对话框提示删除。
- 响应编辑按钮需要在两个 Activity 中传递数据。本 APP 利用 intent 传递数据。新建 itent, 向 Intent 写入数据,调用方法 putExtra(),将 key-value 写入内部 Bundle mExtras,方法中传入名和值。然后启动 EditActivity。
日期选择
本 APP 用到 DatePicker 组件实现日期选择功能。
- 新建日期选择布局,在布局中放置 DatePicker,完成布局。
- 通过 Calendar 类型的 c.get(Calendar.XXX)函数在 EditActivity 的 onCreate 函数中获取当前日期。连接获取的日期,设置为默认的日期,并设置修改按钮,响应点击事件, 新建对话框与含有 DatePicker 的 View 绑定。
- 响应 view 的确定按钮,获取当前选择的年月日拼 接成字符串,传送给类成员变量。完成日期选择
查看指定账目
有选择日期查看和查看全部历史账目两个功能。
- 选择日期查看运用到日期选择功能, 弹出对话框选择日期,传回主界面将 item 中符合日期条件的 item 筛选出来调用 holder. mSwipeMenuLayout.setVisibility(View.VISIBLE)显示,调用 View.GONE 隐藏。
- 初始主页面挑选 本月账目显示,若点击历史账目会显示全部账目。同时设置取消选择按钮,将数据显示恢复初始状态。本功能通过设置两个布尔值 flag 进行每个 item 显示与否的判断,以及相应更改判断规则。
账户选择
利用自定义控件 PickerScrollView 实现滚动进行账户的选择。
- 新建类 PickerScrollView,封 装滚动选择器的响应方法和布局绘制。
- 新建类 CommonPopWindow,用于实现 popupwindow, 封装弹出框的布局和新建 Builder 类方法,继承于 PopupWindow.OnDismissListener,设置布局情况实现动画滑滚的效果,并获取点击事件。
- 在主页面中点击修改账户按钮,调用方法 setAddressSelectorPopup(view);出现选择器,getChildView 用于设置默认数据以及滚动监听。
- 数据的设置直接从主页面加载 Account 类的数据,将其账户名称放入滑滚器中。
- 最后新建布局文件,放入两个textview提示,并放入自定义的视图类com.jnu.moneykeep.money.PickerScrollView。
账目 item 布局美化
账目 item 的显示需要根据用户的需求进行强调和区分显示。
- 对金额和账目名称用大字体加粗(textStyle="bold")显示,对于账目的一些详细信息使用小字体,并用不同字体颜色进行信息区分。
- 收入显示为绿色,支出显示为黑色。在显示时对每条 item 进行支出收入类型判断,并 根据判断设置不同的字体颜色(holder.getTextViewXXX().setTextColor)。
- 在 item 之间绘制分割线以及预留一定的间隔使界面看起来更美观。绘制分割线,直接在 RecyclerView 设置布局管理 器(setLayoutManager)的同时使用下面一行代码添加分割线,使用代码 addItemDecoration(new DividerItemDecoration(mainRecyclerView.getContext(), DividerItemDecoration.VERTICAL));绘制分割线。在布局文件 style 中修改分割线的样式。
本月账目情况
本月账目情况包括收入、支出、结余。
- 获取当前的年份和月份,与每个 item 比对,找到当前月份的 item,将其区分为收入和支出,分别相加。并根据删除或修改的账目实时更新汇总内容。计算得到月收入和月支出后,用月收入-月支出得到结余,也需要及时更新。
item 按日期排序
- 在账目类 Money 中重载函数 Comparable,重载方法 compareTo,compareTo()返回值大于 0 表示前一个数据比后一个数据大, 0 表示相等,小于 0 表示前一个数据小于后一个数据,相等时会走到 equals()。
- 格式化日期为"yyyy 年 MM 月 dd 日",再进行比对。
- 在每次显示账 目的 fragment 更新时都调用 Collections.sort(MoneyList);这个方法为列表值排序。
- 为了方便用户查看最近的账目,需要对账目进行降序排列,故传入 Collections.reverseOrder(), 返回一个倒叙的 Comparator 对象。
账目类型分类导航栏
实现原理是一个 viewpager 嵌套一个 gridview。
- 创建一个 gridview 布局文件,在其中放 置 GridView 布局,并在主布局中添加 viewpager(android.support.v4.view.ViewPager)。
- 为了代码简洁,需要新建资源文件 arrays.xml,将图片的文字和图片放到 arrays.xml 中的数组。
- 新建一个 类 Classify_ItemInfo 存放图片和文字信息。 初始化数据 gridview 和 viewpager。
- 绑定布局,通过 inflate 加载 gridview 的布局,初始化 gridview 的控件并绑定,为 gridview 设置适配器,往 list 集合里添加 gridview,为 viewpager 设 置适配器。
- 设置两个 pagerView 和两个 GridView,实现翻页显示功能。
- 获取 arrays.xml 中的数据。从 arrays.xml 文件中通过 getResources().getStringArray 和 obtainTypedArray,拿到对应的图片和文字后,通过 for 循环遍历分类的图片和文字信息,添加 判断条件,<8 则添加进 OneData,其他添加进 TwoData。
- 设置适配器。viewPager 适配器中添加构造函数和相应的方法,Gridview 适配器中添加 View getView 方法,实现加载 gridView 中的子布局,初始化控件,为 gridView 子布局布局中添加图片和文字。
测试及使用说明
主界面
- 主界面顶部有图标,点击出现用户菜单栏。有三个标签,主页面为账目明细页面。
- 每条账目还可右滑,出现删除和编辑按钮,可进行相应功能,删除时出现提示框如图 5。
- 右一为增加账目功能。底部左一为选择日期显示该日期的账目,左二为取消选择按钮,点击将页面显示条目恢复为默认状态。
- 历史查看可显示所有时间的账目。
添加账目
点击主页面底部加号,进入添加账目页面。顶部是一个分类页面,拥有两页分类可滑动, 点击分类后出现提示框,并自动填充项目名称。文章来源:https://www.toymoban.com/news/detail-401459.html
文章来源地址https://www.toymoban.com/news/detail-401459.html
开发参考
- 本APP gitee 地址:https://gitee.com/gulaks/Moneykeep
- 其他参考网址:
- 分类导航栏:https://www.freesion.com/article/6375976829/ item
- 左滑:https://blog.csdn.net/zhaihaohao1/article/details/80774749
- 单选按钮:https://blog.csdn.net/qq_28057577/article/details/52121977
- 右滑用户栏:https://zhuanlan.zhihu.com/p/234598182
- 带输入对话框:https://blog.csdn.net/bingqingsuimeng/article/details/51433998
- 选择显示:https://blog.csdn.net/weixin_41654311/article/details/102989131
到了这里,关于基于Android Studio的记账类app开发的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!