安卓--记账软件课程设计

安卓课程设计

记账软件课程设计

目录

1 引言............................................................................................................................................................. 2

1.1 背景................................................................................................................................................ 3

1.1.1 课程背景........................................................................................................................... 3

1.1.2 开发与运行环境............................................................................................................... 3

2 项目总体分析............................................................................................................................................. 3

2.1 项目架构分析(根据页面区分).............................................................................................. 3

2.1.1 首次启动页....................................................................................................................... 3

2.1.2 首页.................................................................................................................................... 3

2.1.3 记账页............................................................................................................................... 3

2.1.4 分类页............................................................................................................................... 3

2.1.5 图表页............................................................................................................................... 3

2.1.6 页面跳转关系................................................................................................................... 3

2.2 功能模块分析................................................................................................................................ 4

2.2.1 账目显示&记账&分类管理............................................................................................. 4

2.2.2 数据统计&数据查询........................................................................................................ 5

3 数据库设计................................................................................................................................................. 5

3.1 数据库概念分析............................................................................................................................ 5

3.1.1 确认所需数据库............................................................................................................... 5

3.1.2 数据库所需操作分析...................................................................................................... 5

3.2 表设计............................................................................................................................................ 5

3.3 关系设计........................................................................................................................................ 6

4 类设计......................................................................................................................................................... 6

4.1 账单类............................................................................................................................................ 6

4.2 分类类............................................................................................................................................ 6

5 项目实现..................................................................................................................................................... 7

5.1 UI..................................................................................................................................................... 7

5.1.4 分类页............................................................................................................................. 13

5.2 功能模块逻辑实现..................................................................................................................... 17

6 测试........................................................................................................................................................... 33

6.1 测试内容及遇到的问题............................................................................................................. 33

·测试内容&遇到的问题&解决方法:.................................................................................. 33

6.2 可优化方案.................................................................................................................................. 34

6.3 未解决问题&部分修改.............................................................................................................. 34

7 难点分析................................................................................................................................................... 34

7.1 数据库的操作代码编写............................................................................................................. 34

7.2 RecyclerView的显示和布局以及item样式设置................................................................... 34

7.3 隐藏显示新界面及动画的使用................................................................................................ 34

7.4 复选框的相关操作..................................................................................................................... 34

7.5 图表的统计显示......................................................................................................................... 34

8 总结........................................................................................................................................................... 35

  1. 引言
    1. 背景
      1. 课程背景

《移动软件开发》课程设计:设计实现基于Android平台的记账app。简单分析一下自己的需求,对于衣食住行进行分类,然后记录每天的时间,记录下消费的原因,最重要的就是金额了,以及收入进账的记录。做每个月账单统计,分析自己当前的支出和收入。

      1. 开发与运行环境

Winxp/win7/win8/win10/vista/win2003server, android studio。

数据库:SQLite

JDK1.7 及以上

兼容 Android 版本 4.3 及以上版本

目标设备:android 手机

  1. 项目总体分析
    1. 项目架构分析(根据页面区分)
      1. 首次启动页

首次使用app,首次加载,点击开启记账,进入首页。

      1. 首页

app主体界面,默认显示手机系统时间当月的账单以及当月的总支出、总收入。用户可通过按键< >查看其它月份账单和支出收入情况。

      1. 记账页

app主要功能界面,主要功能有添加新账目,修改原有账目。

      1. 分类页

分类设置界面,默认显示数据库原有分类条目。用户可长按分类条目显示编辑按钮条,编辑、删除(可多选)分类条目或隐藏编辑按钮条。同时在编辑按钮条隐藏的条件下,用户可以通过点击右下角的添加按钮添加分类条目。

      1. 图表页

数据统计分类显示界面,默认显示手机系统时间当月账单的支出分类圆形图表,用户可通过点击收入按钮查看当月账单的收入分类圆形图表。同时用户可以通过< >按键查看其它月份的分类圆形图表。

      1. 页面跳转关系

       

    1. 功能模块分析
      1. 账目显示&记账&分类管理

·账目显示:读取用户已添加过的当月的所有账单条目显示在【主页】,每一条条目包含【账目类别名称】、【账目收入支出类别】、【账目金额】、【账目时间 24小时制】,按添加顺序(即时间先后顺序)排列。

·记账:点击【+】按钮跳转至【记账页】,账目类别名称默认为“FOOD”,账目收入支出类别默认为“支出”。用户通过输入数字进金额编辑框来设定金额(最大不超过99999),通过点击收入或支出按钮设定支出收入类别,通过点击“FOOD”跳转至【分类页】设定账目类别名称,后台通过读取手机系统时间设定该账目时间。用户也可以长按【主页】显示的item跳转至【记账页】来编辑被长按的item,可以修改此条item的账目类别名称、账目金额、收入或支出类别。用户点击【<】放弃添加账单返回【主页】,点击【保存】按钮确认添加新账目。

·分类管理:读取用户已添加过的所有账单类别显示在[分类页],每一条条目只包含[类别名称],按添加顺序排列。用户通过长按某一条item获取【编辑按钮条】以及类别条目的复选框,编辑按钮条包含【撤回】、【编辑】、【删除】三个按钮。点击撤回按钮隐藏编辑按钮条以及类别条目复选框。在复选框选择一个条目的情况下可点击编辑按钮滑出【编辑框】修改类别条目名称,或点击删除按钮删除条目。在复选框多选的情况下隐藏编辑按钮,只可进行删除操作。

      1. 数据统计&数据查询

·数据统计:在【图表】界面统计每个月不同类别的金额收入或支出百分比圆形图表,默认显示手机系统当月支出百分比圆形图表。用户通过点击收入或支出按钮查看当月的收入支出图表。

·数据查询:用户通过点击【<】或【>】按钮查看当月的上一个月或下一个月的账单图表。

  1. 数据库设计
    1. 数据库概念分析
      1. 确认所需数据库

通过功能模块分析可知需要数据增删查改的页面有【记账页】以及【分类页】,所以所需两个表。本项目建立了两个数据库分别存放账单表以及类别表。

数据库1:bill-> 表1:costlist  costDate为主键

数据库2:mClassify-> 表2:classify  classifyName 为主键

      1. 数据库所需操作分析

增:【记账页】的添加账单操作,【分类页】的添加分类操作

删:【分类页】的复选框删除分类操作

查:【记账页】不同月份账单切换显示操作,【分类页】分类条目显示操作

改:【记账页】通过长按【主页】条目进行的修改条目操作,【分类页】分类条目的编辑操作。

    1. 表设计

表1:costlist

数据名称

数据类型

数据含义

costTitle

Varchar

账目类别名称

costDate     primary key

Varchar

账目被添加时的详细时间

costYear

Varchar

账目被添加时的年份

costMonth

Varchar

账目被添加时的月份

costDay

Varchar

账目被添加时的日

costHour

Varchar

账目被添加时的时

costMinute

Varchar

账目被添加时的分

costSecond

Varchar

账目被添加时的秒

costMoney

Varchar

账目金额

costInOut

Varchar

账目支出收入

表2:classify

数据名称

数据类型

数据含义

classifyName  primary key

Varchar

类别名称

costInOut

Varchar

类别支出收入属性

PS:数据库后台会为表单自动插入一个rowid列来记录每一条数据的行数。

    1. 关系设计

  1. 类设计
    1. 账单类

CostBean类

成员变量:(all public)

数据名称

数据类型

数据含义

costTitle

String

账目类别名称

costDate

String

账目被添加时的详细时间

costYear

String

账目被添加时的年份

costMonth

String

账目被添加时的月份

costDay

String

账目被添加时的日

costHour

String

账目被添加时的时

costMinute

String

账目被添加时的分

costSecond

String

账目被添加时的秒

costMoney

String

账目金额

costInOut

String

账目支出收入

    1. 分类类

ClassifyBean类

成员变量:(all public)

数据名称

数据类型

数据含义

classifyName

String

类别名称

costInOut

String

类别支出收入属性

isShow

boolean

复选框是否显示

isChecked

boolean

复选框是否被选中

成员函数:(all public)

函数名称

返回类型

函数功能

getClassifyName

String

获取类别名称

setClassifyName

void

设置类别名称

isShow

boolean

返回复选框是否显示

setShow

void

设置复选框是否选中

isChecked

boolean

返回复选框是否被选中

setChecked

void

设置复选框是否选中选中

  1. 项目实现
    1. UI
      1. 首次启动页

     

效果图如右图所示.

该界面所用控件有ImageView及Button。在首次启动App时作为第一个页面出现。

将logo图片设置在界面适当的位置之后,对button的进行圆角背景色等样式设计。

相关布局文件以及样式文件源码见下方文本框。

activity_main.xml

<RelativeLayout
    android:id="@+id/R_1"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#005ABD">
    <ImageView
        android:id="@+id/img_logo"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/logo"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="140dp"/>
    <Button
        android:id="@+id/btn_start"
        android:layout_width="120dp"
        android:layout_height="40dp"
        android:layout_below="@id/img_logo"
        android:layout_marginTop="240dp"
        android:background="@drawable/btn_start"
        android:text="开启记账"
        android:layout_centerHorizontal="true"
        android:textColor="#ffffff"
        android:textSize="16sp" />
</RelativeLayout>

:

btn_start.xml:

<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="#0066D7" /><!-- 背景填充颜色 -->
    <corners android:radius="5dp" /><!-- 边角圆弧的半径 -->
</shape>

      1. 首页

       

 效果图如右图所示.

该界面所用控件有TextView/Button/RecyclerView。在点击【开始记账】按钮后作为主界面出现。

主要利用相对布局将布局区分成四个部分,标题、页头、显示列表、页尾。

相关主要布局文件以及样式文件源码见下方文本框。

(较为简单部分省略不计)

Activity_home_page.xml:

页头布局:

 

<RelativeLayout
    android:id="@+id/home_page_R_3"
    android:layout_width="match_parent"
    android:layout_height="70dp"
    android:layout_below="@id/home_page_R_2"
    android:background="@drawable/frame">
    <Button
        android:id="@+id/btn_up"
        android:layout_width="30dp"
        android:layout_height="30dp"
        android:layout_marginTop="10dp"
        android:background="@drawable/up" />
    <TextView
        android:id="@+id/tv_month"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="10dp"
        android:text="本月"
        android:textColor="#005ABD"
        android:textSize="20sp"
        android:textStyle="bold" />
    <Button
        android:id="@+id/btn_down"
        android:layout_width="30dp"
        android:layout_height="30dp"
        android:layout_marginLeft="160dp"
        android:layout_marginTop="10dp"
        android:layout_toRightOf="@id/tv_month"
        android:background="@drawable/down" />
    <TextView
        android:id="@+id/tv_expend"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/btn_up"
        android:layout_marginLeft="50dp"
        android:layout_marginTop="4dp"
        android:text="支出 "
        android:textColor="#999999"
        android:textSize="12sp" />
    <TextView
        android:id="@+id/tv_expendnum"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/btn_up"
        android:layout_toRightOf="@id/tv_expend"
        android:text="¥0.00"
        android:textColor="#333333"
        android:textSize="16sp" />
    <TextView
        android:id="@+id/tv_income"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/btn_up"
        android:layout_marginLeft="270dp"
        android:layout_marginTop="4dp"
        android:text="收入 "
        android:textSize="12sp" />

    <TextView
        android:id="@+id/tv_incomenum"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/btn_down"
        android:layout_toRightOf="@id/tv_income"
        android:text="¥0.00"
        android:textColor="#FF0000"
        android:textSize="16sp" />

</RelativeLayout>

frame.xml:

    android:layout_marginTop="10dp"
        android:text="本月"
        android:textColor="#005ABD"
        android:textSize="20sp"
        android:textStyle="bold" />
    <Button
        android:id="@+id/btn_down"
        android:layout_width="30dp"
        android:layout_height="30dp"
        android:layout_marginLeft="160dp"
        android:layout_marginTop="10dp"
        android:layout_toRightOf="@id/tv_month"
        android:background="@drawable/down" />
    <TextView
        android:id="@+id/tv_expend"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/btn_up"
        android:layout_marginLeft="50dp"
        android:layout_marginTop="4dp"
        android:text="支出 "
        android:textColor="#999999"
        android:textSize="12sp" />
    <TextView
        android:id="@+id/tv_expendnum"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/btn_up"
        android:layout_toRightOf="@id/tv_expend"
        android:text="¥0.00"
        android:textColor="#333333"
        android:textSize="16sp" />
        android:textColor="#FF0000"
        android:textSize="16sp" />

//“收入”TextView同理,这里略去。
</RelativeLayout>

<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <stroke android:width="0.5dp" android:color="#F2F2F2" /><!-- 描边,边框宽度、颜色 -->
    <padding android:left="3dp" android:top="3dp" android:right="3dp" android:bottom="3dp" /><!-- 四周留出来的空白 -->
</shape>

页尾:

 

<RelativeLayout
    android:id="@+id/home_page_R_5"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_below="@id/home_page_R_4"
    android:background="@drawable/frame">
    <Button
        android:id="@+id/btn_payment"
        android:layout_width="30dp"
        android:layout_height="30dp"
        android:layout_centerVertical="true"
        android:layout_marginLeft="40dp"
        android:background="@drawable/payment1" />
    <TextView
        android:id="@+id/tv_paynote"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/btn_payment"
        android:layout_marginLeft="40dp"
        android:text="账本"
        android:textSize="15dp" />
    <Button
        android:id="@+id/btn_add"
        android:layout_width="60dp"
        android:layout_height="60dp"
        android:layout_centerInParent="true"
        android:background="@drawable/add" />

//“图表”Button同理,这里略去
   </RelativeLayout>

显示列表利用RecyclerView控件显示:

<android.support.v7.widget.RecyclerView
             android:id="@+id/id_recylerView"
             android:layout_width="match_parent"
             android:layout_height="match_parent">
         </android.support.v7.widget.RecyclerView>

同时为RecyclerView内部所要显示的list_item设定一个样式,该样式为list_item.xml源码及效果图如下:

 

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:background="#ffffffff"
    android:layout_width="match_parent"
    android:layout_height="70dp">
    <TextView
        android:id="@+id/tv_title"
        android:layout_width="200dp"
        android:layout_height="40dp"
        android:layout_marginLeft="10dp"
        android:text="costTitle"
        android:textColor="#333333"
        android:ellipsize="marquee"
        android:textSize="16sp"
        android:layout_alignParentLeft="true"
        android:gravity="left|bottom"/>
    <TextView
        android:id="@+id/tv_in_out"
        android:layout_width="200dp"
        android:layout_height="30dp"
        android:layout_marginLeft="10dp"
        android:gravity="left|top"
        android:textSize="13dp"
        android:layout_below="@id/tv_title"
        android:text="in_out"/>
    <TextView
        android:id="@+id/tv_date"
        android:layout_width="wrap_content"
        android:layout_height="30dp"
        android:layout_below="@id/tv_cost"
        android:layout_marginRight="20dp"
        android:layout_alignParentRight="true"
        android:gravity="center|top"
        android:textSize="11sp"
        android:text="costDate"/>
    <TextView
        android:id="@+id/tv_cost"
        android:layout_width="wrap_content"
        android:layout_height="40dp"
        android:gravity="bottom|right"
        android:textSize="15sp"
        android:textColor="#ff0000"
        android:layout_marginRight="20dp"
        android:layout_alignParentRight="true"
        android:text="+30.00"/>

</RelativeLayout>

      1. android:layout_width="wrap_content"
                android:layout_height="40dp"
                android:gravity="bottom|right"
                android:textSize="15sp"
                android:textColor="#ff0000"
                android:layout_marginRight="20dp"
                android:layout_alignParentRight="true"
                android:text="+30.00"/>
        </RelativeLayout>

        记账页

效果图如右图所示.

 

该界面所用控件有TextView/Button/EditText。在点击【+】按钮后作为编辑界面出现。

主要利用相对布局将布局区分成四个部分,标题、按钮条、编辑列表、保存按钮。

相关主要布局文件以及样式文件源码见下方文本框。

(较为简单部分省略不计)

 

Activity_account.xml:

<RelativeLayout
    android:id="@+id/account_R_5"
    android:layout_width="match_parent"
    android:layout_height="60dp"
    android:background="@drawable/frame1">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="金额"
        android:textSize="20dp"
        android:layout_centerVertical="true"
        android:layout_marginLeft="10dp"
        android:textColor="#333333"/>
    <TextView
        android:id="@+id/tv_y"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="¥"
        android:layout_toLeftOf="@id/et_money"
        android:textSize="26dp"
        android:layout_marginRight="5dp"
        android:textStyle="bold"
        android:layout_centerVertical="true"
        android:textColor="#333333"/>
    <EditText
        android:id="@+id/et_money"
        android:hint="0.00"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_marginRight="30dp"
        android:singleLine="true"
        android:maxLength="5"
        android:textColorHint="#333333"
        android:layout_centerVertical="true"
        android:textSize="26dp"
        android:textStyle="bold"
        android:background="@null"/>


</RelativeLayout>
<RelativeLayout
    android:id="@+id/account_R_6"
    android:layout_below="@id/account_R_5"
    android:layout_width="match_parent"
    android:layout_height="60dp"
    android:background="@drawable/frame1">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="分类"
        android:textSize="20dp"
        android:layout_centerVertical="true"
        android:layout_marginLeft="10dp"
        android:textColor="#333333"/>
    <Button
        android:id="@+id/btn_classify"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginRight="30dp"
        android:layout_alignParentRight="true"
        android:text="FOOD"
        android:textColor="#808080"
        android:gravity="right|center"
        android:layout_centerVertical="true"
        android:textSize="18dp"
        android:background="@null"/>

</RelativeLayout>

android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="¥"
        android:layout_toLeftOf="@id/et_money"
        android:textSize="26dp"
        android:layout_marginRight="5dp"
        android:textStyle="bold"
        android:layout_centerVertical="true"
        android:textColor="#333333"/>
    <EditText
        android:id="@+id/et_money"
        android:hint="0.00"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_marginRight="30dp"
        android:singleLine="true"
        android:maxLength="5"
        android:textColorHint="#333333"
        android:layout_centerVertical="true"
        android:textSize="26dp"
        android:textStyle="bold"
        android:background="@null"/>
</RelativeLayout>
        //“分类”条同理,这里略去

      1. 分类页

效果图如右图所示.

 

该界面所用控件有RecyclerView。在点击【“类别”】按钮后作为选择界面出现。

主要利用相对布局将布局区分成三个部分,标题、类别列表、添加按钮。

【类别列表】布局部分同主页的布局,这里省略。

相关主要布局文件以及样式文件源码见下方文本框。

(较为简单部分省略不计)

右下角Button布局方法:

<Button
    android:id="@+id/btn_add_item"
    android:layout_width="55dp"
    android:layout_height="55dp"
    android:layout_alignParentRight="true"
    android:layout_alignParentBottom="true"
    android:layout_marginRight="15dp"
    android:layout_marginBottom="15dp"
    android:background="@drawable/add"
    android:visibility="visible"
    />

该界面item样式,classify.xml。(默认CheckBox被隐藏了)

 

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:background="#ffffffff"
    android:layout_width="match_parent"
    android:layout_height="60dp">
    <TextView
        android:id="@+id/tv_title"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginLeft="10dp"
        android:text="costTitle"
        android:textColor="#333333"
        android:ellipsize="marquee"
        android:textSize="22sp"
        android:layout_alignParentLeft="true"
        android:gravity="left|center"/>
    <CheckBox
        android:id="@+id/recylerView_long_checkbox"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_alignParentRight="true"
        android:layout_marginRight="10dp"
        android:clickable="false"
        android:visibility="gone"
        style="@style/MyCheckBox"/>
</RelativeLayout>

为CheckBox设置新样式,在styles.xml中添加如下代码,将未被点击和被点击的CheckBox图片导入即可使用。添加的代码和复选框效果如下:

 

<style name="MyCheckBox" parent="@android:style/Widget.CompoundButton.CheckBox">
    <item name="android:button">@drawable/checkbox_selector</item>
</style>

      1. 图表页

效果图如右图所示.

 

该界面所用控件有TextView。在点击【图表】按钮后作为选择界面出现。

主要利用相对布局将布局区分成四个个部分,页头、按钮条、图表、页尾。

【页头】【页尾】布局部分同主页的布局,【按钮】同记账页部分布局,这里省略。

相关主要布局文件以及样式文件源码见下方文本框。

(较为简单部分省略不计)

图表布局方法:

//圆形图表部分:

 <com.hedan.piechart_library.PieChart_View
        android:id="@+id/pie_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:padding="10dp"
        app:isAnimation="true"
        app:isTouchFlag="true"
        app:animaDuration="1000"
        app:mRadius="100dp"
        app:nameColor="#f00"
        app:name=" "
        app:nameSize="16sp"
        app:nameOrientation="horizontal"
        app:pieChartWidth="35dp"
        app:alphaWidth="10dp"
        app:alphaPieColor="#fff"
        app:alphaPieTran="100"
        app:segmentAngle="0.5"
        app:startAngle="180"
        app:textColor="#000"
        app:textSize="12sp"
        app:textOrientation="path"
        app:inCricleColor="#eeeeee"
        />
</RelativeLayout>


<LinearLayout
    android:id="@+id/laout_four"
    android:layout_below="@id/layout_three"
    android:layout_width="match_parent"
    android:layout_margin="10dp"
    android:layout_height="100dp"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="50dp"
        android:layout_gravity="center">
        <RelativeLayout
            android:id="@+id/expenditure_1"
            android:layout_width="80dp"
            android:layout_height="50dp"
            android:orientation="horizontal"
            android:layout_weight="1"
            >
            <TextView
                android:id="@+id/expcolor_1"
                android:layout_width="12dp"
                android:layout_height="12dp"
                android:background="#0baf97"
                android:layout_centerVertical="true"
                />
            <TextView
                android:id="@+id/expname_1"
                android:layout_toRightOf="@id/expcolor_1"
                android:layout_width="60dp"
                android:layout_height="30dp"
                android:layout_centerVertical="true"
                android:text="花费一"
                android:gravity="center"/>
        </RelativeLayout>

app:mRadius="100dp"
        app:nameColor="#f00"
        app:name=" "
        app:nameSize="16sp"
        app:nameOrientation="horizontal"
        app:pieChartWidth="35dp"
        app:alphaWidth="10dp"
        app:alphaPieColor="#fff"
        app:alphaPieTran="100"
        app:segmentAngle="0.5"
        app:startAngle="180"
        app:textColor="#000"
        app:textSize="12sp"
        app:textOrientation="path"
        app:inCricleColor="#eeeeee"
        />

//类别颜色显示部分
        <RelativeLayout
            android:id="@+id/expenditure_1"
            android:layout_width="80dp"
            android:layout_height="50dp"
            android:orientation="horizontal"
            android:layout_weight="1"
            >
            <TextView
                android:id="@+id/expcolor_1"
                android:layout_width="12dp"
                android:layout_height="12dp"
                android:background="#0baf97"
                android:layout_centerVertical="true"
                />
            <TextView
                android:id="@+id/expname_1"
                android:layout_toRightOf="@id/expcolor_1"
                android:layout_width="60dp"
                android:layout_height="30dp"
                android:layout_centerVertical="true"
                android:text="花费一"
                android:gravity="center"/>
        </RelativeLayout>

    1. 功能模块逻辑实现
      1. 主页

主页所包含的功能有:【不同月份账目显示】【跳转至其他页面】【获取其他页面发送的数据】。首先创建一个账单类,根据所需功能设计类,具体类设计见上文。根据布局文件设计,账目需要显示在主页的RecyclerView当中。同时根据账单类设计一个数据库,来进行数据库的操作。Home_page主要代码(有大部分删减,具体见打包工程)如下,具体功能实现见注释。

onCreate函数:

protected void onCreate(Bundle savedInstanceState) {
    //自动生成代码 略
         //获取布局文件里的控件 这里以添加按钮为例,其他略
    btn_add = findViewById(R.id.btn_add);
    //获取手机系统当前时间
    date = new Time();
    date.setToNow();
    month=date.month;
    month++;
    tv_month.setText(String.valueOf(month)+"月");
    //add按钮监听,页面跳转至记账页 同时传送“chart”参数用于判断从哪个界面跳转
    btn_add.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent intent = new Intent(home_page.this, Account.class);
            intent.putExtra("chart",0);
            startActivityForResult(intent,1);
        }
    });
         //图表按钮监听 跳转至图表界面 同时改变图表和账本按钮的颜色(即替换背景图片)
    btn_piechart.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent intent = new Intent(home_page.this, Chart.class);
            btn_piechart.setBackgroundResource(R.drawable.piechart1);
            btn_payment.setBackgroundResource(R.drawable.payment);
            startActivity(intent);
        }
    });
    btn_up.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if(month<12)
            {
                month++;
                tv_month.setText(String.valueOf(month)+"月");
                initList(month);
                mAdapter.notifyDataSetChanged();
            }
        }
    });
    btn_down.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if(month>1)
            {

                month--;
                tv_month.setText(String.valueOf(month)+"月");
                initList(month);
                mAdapter.notifyDataSetChanged();
            }
        }
    });

    mDatabaseHelper = new DataBaseHelper(this);
    mList = new ArrayList<CostBean>();

    initList(date.month+1);
    initView();
    mAdapter = new CostListAdapter(this,mList);
    mRecyclerView.setAdapter(mAdapter);


    //设置RecyclerView的布局管理
    LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false);
    mRecyclerView.setLayoutManager(linearLayoutManager);

    mRecyclerView.setItemAnimator(new DefaultItemAnimator());

    //设置RecyclerView的Item分割线
    mRecyclerView.addItemDecoration(new DividerItemDecoration(this,DividerItemDecoration.VERTICAL_LIST));

    mAdapter.setOnItemClickListener(new CostListAdapter.OnItemClickListener() {
        @Override
        public void onItemClick(View view, int position) {
            Toast.makeText(home_page.this,"click"+position,Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onItemLongClick(View view, int position) {
            Toast.makeText(home_page.this,"long click"+position,Toast.LENGTH_SHORT).show();
            Intent intent = new Intent(home_page.this, Account.class);
            CostBean bean = mList.get(position);
            intent.putExtra("costTile",bean.costTile);
            intent.putExtra("costMoney",bean.costMoney);
            intent.putExtra("costInOut",bean.costInOut);
            intent.putExtra("position",position);
            intent.putExtra("chart",3);
            startActivity(intent);
        }
    });

    if(checkIntentAvailable(getIntent()))
    {
        int i = getIntent().getIntExtra("chart",0);
        if(i==1)
        {
            Intent chartdata = getIntent();
            CostBean costBean = new CostBean();
            costBean.costDate = chartdata.getStringExtra("Date");
            costBean.costYear = chartdata.getStringExtra("Year");
            costBean.costMonth = chartdata.getStringExtra("Month");
            costBean.costDay = chartdata.getStringExtra("Day");
            costBean.costMinute = chartdata.getStringExtra("Minute");
            costBean.costHour = chartdata.getStringExtra("Hour");
            costBean.costSecond = chartdata.getStringExtra("Second");
            Toast.makeText(home_page.this,costBean.costSecond,Toast.LENGTH_SHORT).show();

            costBean.costTile = chartdata.getStringExtra("classify");
            boolean inorout = chartdata.getBooleanExtra("inorout",false);
            if(inorout)
            {
                costBean.costInOut = "支出";
                costBean.costMoney = "-" + chartdata.getStringExtra("money");
            }
            else
            {
                costBean.costInOut = "收入";
                costBean.costMoney = "+" + chartdata.getStringExtra("money");
            }
            mDatabaseHelper.insertCost(costBean);
            Toast.makeText(home_page.this,"数据库"+mDatabaseHelper.idd,Toast.LENGTH_SHORT).show();
            mAdapter.addData(costBean,0);
        }
        else if(i==2)
        {
            Intent chartdata = getIntent();
            int pos = chartdata.getIntExtra("position",0);
            CostBean costBean = mList.get(pos);
            costBean.costTile = chartdata.getStringExtra("classify");
            boolean inorout = chartdata.getBooleanExtra("inorout",false);
            if(inorout)
            {
                costBean.costInOut = "支出";
                costBean.costMoney = "-" + chartdata.getStringExtra("money");
            }
            else
            {
                costBean.costInOut = "收入";
                costBean.costMoney = "+" + chartdata.getStringExtra("money");
            }
            String[] a = new String[1];
            a[0]=costBean.costDate;
            mDatabaseHelper.upgradeCost(costBean,a);
            mAdapter.upgradeData(pos);
        }
        else
        {
            Toast.makeText(home_page.this,"finish",Toast.LENGTH_SHORT).show();
        }
    }
}

//向上改变月份 即查询新月份的数据库显示在RecyclerView当中去

btn_up.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if(month<12)
            {
                month++;
                tv_month.setText(String.valueOf(month)+"月");
                initList(month);
                mAdapter.notifyDataSetChanged();
            }
        }
    });
    //向下改变月份同理 这里略去
    mDatabaseHelper = new DataBaseHelper(this);//创建数据库
    mList = new ArrayList<CostBean>();//创建列表

    initList(date.month+1);//初始化主页账目列表
    initView();//初始化RecyclerView
    mAdapter = new CostListAdapter(this,mList);
    mRecyclerView.setAdapter(mAdapter);//设置Adapter
    //设置RecyclerView的布局管理
    LinearLayoutManager linearLayoutManager

= new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false);
    mRecyclerView.setLayoutManager(linearLayoutManager);
    mRecyclerView.setItemAnimator(new DefaultItemAnimator());
    //设置RecyclerView的Item分割线
    mRecyclerView.addItemDecoration(new DividerItemDecoration(this,DividerItemDecoration.VERTICAL_LIST));
         //设置listitem按键监听  长按跳转至记账页修改已有item数据
    mAdapter.setOnItemClickListener(new CostListAdapter.OnItemClickListener() {
        public void onItemLongClick(View view, int position) {
            Toast.makeText(home_page.this,"long click"+position,Toast.LENGTH_SHORT).show();
            Intent intent = new Intent(home_page.this, Account.class);
            CostBean bean = mList.get(position);
            intent.putExtra("costTile",bean.costTile);
            intent.putExtra("costMoney",bean.costMoney);
            intent.putExtra("costInOut",bean.costInOut);
            intent.putExtra("position",position);
            intent.putExtra("chart",3);
            startActivity(intent);
        }
    });
        
    if(checkIntentAvailable(getIntent()))
    {
        int i = getIntent().getIntExtra("chart",0);
        if(i==1)
        {
            Intent chartdata = getIntent();
            CostBean costBean = new CostBean();
            costBean.costDate = chartdata.getStringExtra("Date");
            costBean.costYear = chartdata.getStringExtra("Year");
            costBean.costMonth = chartdata.getStringExtra("Month");
            costBean.costDay = chartdata.getStringExtra("Day");
            costBean.costMinute = chartdata.getStringExtra("Minute");
            costBean.costHour = chartdata.getStringExtra("Hour");
            costBean.costSecond = chartdata.getStringExtra("Second");
            Toast.makeText(home_page.this,costBean.costSecond,Toast.LENGTH_SHORT).show();

            costBean.costTile = chartdata.getStringExtra("classify");
            boolean inorout = chartdata.getBooleanExtra("inorout",false);
            if(inorout)
            {
                costBean.costInOut = "支出";
                costBean.costMoney = "-" + chartdata.getStringExtra("money");
            }
            else
            {
                costBean.costInOut = "收入";
                costBean.costMoney = "+" + chartdata.getStringExtra("money");
            }
            mDatabaseHelper.insertCost(costBean);
            Toast.makeText(home_page.this,"数据库"+mDatabaseHelper.idd,Toast.LENGTH_SHORT).show();
            mAdapter.addData(costBean,0);
        }
        else if(i==2)
        {
            Intent chartdata = getIntent();
            int pos = chartdata.getIntExtra("position",0);
            CostBean costBean = mList.get(pos);
            costBean.costTile = chartdata.getStringExtra("classify");
            boolean inorout = chartdata.getBooleanExtra("inorout",false);
            if(inorout)
            {
                costBean.costInOut = "支出";
                costBean.costMoney = "-" + chartdata.getStringExtra("money");
            }
            else
            {
                costBean.costInOut = "收入";
                costBean.costMoney = "+" + chartdata.getStringExtra("money");
            }
            String[] a = new String[1];
            a[0]=costBean.costDate;
            mDatabaseHelper.upgradeCost(costBean,a);
            mAdapter.upgradeData(pos);
        }
        else
        {
            Toast.makeText(home_page.this,"finish",Toast.LENGTH_SHORT).show();
        }
    }
}

//判断Intent是否成功获取
    if(checkIntentAvailable(getIntent()))
    {
        int i = getIntent().getIntExtra("chart",0);
        if(i==1)
        {

//设置数据并添加数据
            Intent chartdata = getIntent();
            CostBean costBean = new CostBean();
            costBean.costDate = chartdata.getStringExtra("Date");
            costBean.costYear = chartdata.getStringExtra("Year");
            costBean.costMonth = chartdata.getStringExtra("Month");
            costBean.costDay = chartdata.getStringExtra("Day");
            costBean.costMinute = chartdata.getStringExtra("Minute");
            costBean.costHour = chartdata.getStringExtra("Hour");
            costBean.costSecond = chartdata.getStringExtra("Second");
           Toast.makeText(home_page.this,costBean.costSecond,Toast.LENGTH_SHORT).show();
            costBean.costTile = chartdata.getStringExtra("classify");
            boolean inorout = chartdata.getBooleanExtra("inorout",false);
            if(inorout)
            {
                costBean.costInOut = "支出";
                costBean.costMoney = "-" + chartdata.getStringExtra("money");
            }
            else
            {
                costBean.costInOut = "收入";
                costBean.costMoney = "+" + chartdata.getStringExtra("money");
            }
            mDatabaseHelper.insertCost(costBean);
            mAdapter.addData(costBean,0);
        }
        else if(i==2)
        {
             //设置要修改的数据&更新数据 与添加数据代码基本同理 这里略去
            String[] a = new String[1];
            a[0]=costBean.costDate;
            mDatabaseHelper.upgradeCost(costBean,a);
            mAdapter.upgradeData(pos);
        }
    }
}

初始化列表以及初始化RecyclerView:

private void initList(int month)//初始化列表
    {
         mList.clear();//清空列表并初始化收入支出月份
         exp_num_month=0;
         income_num_month=0;
        //游标 从数据库中读取账目数据项并显示在list中
        Cursor cursor = mDatabaseHelper.getAllCostData();
        if(cursor != null)
        {
            img_write.setVisibility(View.GONE);
            tv_sentence.setVisibility(View.GONE);
            while (cursor.moveToNext())
            {
                CostBean costBean = new CostBean();
                costBean.costTile = cursor.getString(cursor.getColumnIndex("costTile"));
                //其他成员变量同理赋值 这里略去
                if(month-1==Integer.parseInt(costBean.costMonth))
                {
                    mList.add(costBean);
                    int temp=Integer.parseInt(cursor.getString(8));
                    if(temp>=0) income_num_month+=Math.abs(temp);
                    else exp_num_month+=Math.abs(temp);
                }
            }
            cursor.close();
            expnum.setText(String.valueOf(exp_num_month));
            incomum.setText(String.valueOf(income_num_month));
        }

else
{
    img_write.setVisibility(View.VISIBLE);
    tv_sentence.setVisibility(View.VISIBLE);
}
    }

//初始化View
    private void initView()
    {
        mRecyclerView = findViewById(R.id.id_recylerView);
    }

public boolean checkIntentAvailable(Intent intent){
             if (intent.resolveActivity(getPackageManager()) != null) return true;

else return  false;
}

获取下一个界面finish()后向本界面(即上一个界面发送的数据):

checkIntentAvailable函数实现:

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    switch (requestCode){
        case 1:
            if(resultCode == RESULT_OK){
                //创建一个CostBean类对象存储下一个界面发送的数据

//与上文初始化裂变代码相似 这里略去
                mDatabaseHelper.insertCost(costBean);//向数据库插入新数据
                mAdapter.addData(costBean,0);//向显示账目添加数据
                initList(month);//刷新列表
            }
            break;
        default:
            break;
    }
}

      1. 主页相关:DatabaseHelper操作类&RecyclerView.Adapter操作类

DatabaseHelper:

public class DataBaseHelper extends SQLiteOpenHelper {

public long idd = 0;
    public DataBaseHelper(Context context){
        super(context,"9",null,1);//“9”是数据库名 被误改了 这里就不改回去了
    }
    public void onCreate(SQLiteDatabase db) //创建表
    { db.execSQL("create table costlist(" +
                "costTile varchar," +
                "costDate varchar primary key," +
                "costYear varchar," +
                "costMonth varchar," +
                "costDay varchar," +
                "costHour varchar," +
                "costMinute varchar," +
                "costSecond varchar," +
                "costMoney varchar," +
                "costInOut varchar)");
    }

    public void  insertCost(CostBean costBean)
    {
        //这里ID出了问题
        SQLiteDatabase database = getWritableDatabase();
        ContentValues cv = new ContentValues();
        //cv.put("id",i++);
        cv.put("costTile",costBean.costTile);
        cv.put("costDate",costBean.costDate);
        cv.put("costYear",costBean.costYear);
        cv.put("costMonth",costBean.costMonth);
        cv.put("costDay",costBean.costDay);
        cv.put("costHour",costBean.costHour);
        cv.put("costMinute",costBean.costMinute);
        cv.put("costSecond",costBean.costSecond);
        cv.put("costMoney",costBean.costMoney);
        cv.put("costInOut",costBean.costInOut);
        idd = database.insert("costlist",null,cv);
    }


    public Cursor getAllCostData()
    {
        SQLiteDatabase database = getWritableDatabase();
        return database.query("costlist",null,null,null,null,null,"costDate " + "ASC");
    }

    public  void onUpgrade(SQLiteDatabase db,int oldVersion,int newVersion)
    {

    }

    public void upgradeCost(CostBean costBean,String[] msg)
    {
        SQLiteDatabase database = getWritableDatabase();
        ContentValues cv = new ContentValues();
        cv.put("costTile",costBean.costTile);
        cv.put("costDate",costBean.costDate);
        cv.put("costYear",costBean.costYear);
        cv.put("costMonth",costBean.costMonth);
        cv.put("costDay",costBean.costDay);
        cv.put("costHour",costBean.costHour);
        cv.put("costMinute",costBean.costMinute);
        cv.put("costSecond",costBean.costSecond);
        cv.put("costMoney",costBean.costMoney);
        cv.put("costInOut",costBean.costInOut);
        database.update("costlist",cv,"costDate=?",msg);
    }


    public void deleteCost()
    {

    }

    public void deleteAllData()
    {
        SQLiteDatabase database = getWritableDatabase();
        database.delete("costlist",null,null);
    }

}

  "costMoney varchar," +
                "costInOut varchar)");
    }
    public void  insertCost(CostBean costBean)//插入数据
    {
        SQLiteDatabase database = getWritableDatabase();
        ContentValues cv = new ContentValues();
        cv.put("costTile",costBean.costTile);//其他成员变量同理 这里略去
        idd = database.insert("costlist",null,cv);
    }
    public Cursor getAllCostData()//获取全部数据
    {
        SQLiteDatabase database = getWritableDatabase();
        return database.query("costlist",null,null,null,null,null,"costDate " + "ASC");
    }
    public void upgradeCost(CostBean costBean,String[] msg)//更新数据
    {
        SQLiteDatabase database = getWritableDatabase();
        ContentValues cv = new ContentValues();
        cv.put("costTile",costBean.costTile);//其他成员变量同理 这里略去
        database.update("costlist",cv,"costDate=?",msg);
    }
    public void deleteAllData()//删除所有数据
    {
        SQLiteDatabase database = getWritableDatabase();
        database.delete("costlist",null,null);
    }
}

CostListAdapter:

public class CostListAdapter extends RecyclerView.Adapter<MyViewHolder> {

//列表 布局
    private List<CostBean> mList;
    private Context mContext;
    private LayoutInflater mInflater;

//设置按键监听接口
    public interface OnItemClickListener
    {
        void onItemClick(View view,int position);
        void onItemLongClick(View view,int position);
    }
    private OnItemClickListener mOnItemClickListener;
    public void setOnItemClickListener(OnItemClickListener listener)
    {
        this.mOnItemClickListener = listener;
    }


    public CostListAdapter(Context context, List<CostBean> list){
        this.mContext = context;
        this.mList = list;
        mInflater = LayoutInflater.from(context);
    }


    @NonNull
    @Override
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        View view = mInflater.inflate(R.layout.list_item,viewGroup,false);
        MyViewHolder viewHolder = new MyViewHolder(view);
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(@NonNull final MyViewHolder holder,final int pos) {
        holder.tv_title.setText(mList.get(pos).costTile);
        holder.tv_in_out.setText(mList.get(pos).costInOut);
        String time = mList.get(pos).costMinute;
        if(time.length()<2)
        {
            String temp = "0";
            time = temp + time;
        }
        holder.tv_date.setText(mList.get(pos).costHour + ":" + time);
        holder.tv_cost.setText(mList.get(pos).costMoney);
        if(holder.tv_in_out.getText().equals("支出"))
        {
            holder.tv_cost.setTextColor(Color.parseColor("#333333"));
        }
        else
        {
            holder.tv_cost.setTextColor(Color.parseColor("#ff0000"));
        }


        //item点击事件回调
        if(mOnItemClickListener != null)
        {
            holder.itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    mOnItemClickListener.onItemClick(holder.itemView,pos);
                }
            });

            holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
                @Override
                public boolean onLongClick(View v) {
                    mOnItemClickListener.onItemLongClick(holder.itemView,pos);
                    return false;
                }
            });
        }

    }

    @Override
    public int getItemCount() {
        return mList.size();
    }

    public Object getItem(int position)
    {
        return position;
    }

    public long getItemId(int position)
    {
        return position;
    }

    public void addData(CostBean costBean,int pos)
    {
//        CostBean costBean = new CostBean();
//        costBean.costDate = "time";
//        costBean.costTile = "添加";
//        costBean.costInOut = "支出";
//        costBean.costMoney = "100";
        mList.add(pos,costBean);
        notifyItemInserted(pos);
    }

    public void deleteData(int pos)
    {
        mList.remove(pos);
        notifyItemRemoved(pos);
    }

    public void upgradeData(int pos)
    {
        notifyItemChanged(pos);
    }



    public View getView(int position,View convertView, ViewGroup parent)
    {
        MyViewHolder viewHolder;
        if(convertView==null)
        {
            viewHolder = new MyViewHolder(convertView);
        }
        return null;
    }
}

class MyViewHolder extends ViewHolder
{
    TextView tv_title;
    TextView tv_in_out;
    TextView tv_date;
    TextView tv_cost;
    public MyViewHolder(View view)
    {
        super(view);

        tv_title = view.findViewById(R.id.tv_title);
        tv_in_out = view.findViewById(R.id.tv_in_out);
        tv_date = view.findViewById(R.id.tv_date);
        tv_cost = view.findViewById(R.id.tv_cost);
    }
}

public void setOnItemClickListener(OnItemClickListener listener)
    {
        this.mOnItemClickListener = listener;
    }

    public CostListAdapter(Context context, List<CostBean> list){
        this.mContext = context;
        this.mList = list;
        mInflater = LayoutInflater.from(context);
    }
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        View view = mInflater.inflate(R.layout.list_item,viewGroup,false);
        MyViewHolder viewHolder = new MyViewHolder(view);
        return viewHolder;
    }
    public void onBindViewHolder(@NonNull final MyViewHolder holder,final int pos) {
        holder.tv_title.setText(mList.get(pos).costTile);设定item内部控件显示内容
        holder.tv_in_out.setText(mList.get(pos).costInOut);
        String time = mList.get(pos).costMinute;
        if(time.length()<2)//时间显示格式
        {
            String temp = "0";
            time = temp + time;
        }
        holder.tv_date.setText(mList.get(pos).costHour + ":" + time);
        holder.tv_cost.setText(mList.get(pos).costMoney);
        if(holder.tv_in_out.getText().equals("支出"))//收入支出类型显示颜色
        {
            holder.tv_cost.setTextColor(Color.parseColor("#333333"));
        }
        else
        {
            holder.tv_cost.setTextColor(Color.parseColor("#ff0000"));
        }
        //item点击事件回调
        if(mOnItemClickListener != null)
        {
            holder.itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    mOnItemClickListener.onItemClick(holder.itemView,pos);
                }
            });

            holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
                @Override
                public boolean onLongClick(View v) {
                    mOnItemClickListener.onItemLongClick(holder.itemView,pos);
                    return false;
                }
            });
        }

    }

    @Override
    public int getItemCount() {
        return mList.size();
    }

    public Object getItem(int position)
    {
        return position;
    }

    public long getItemId(int position)
    {
        return position;
    }

    public void addData(CostBean costBean,int pos)
    {
//        CostBean costBean = new CostBean();
//        costBean.costDate = "time";
//        costBean.costTile = "添加";
//        costBean.costInOut = "支出";
//        costBean.costMoney = "100";
        mList.add(pos,costBean);
        notifyItemInserted(pos);
    }

    public void deleteData(int pos)
    {
        mList.remove(pos);
        notifyItemRemoved(pos);
    }

    public void upgradeData(int pos)
    {
        notifyItemChanged(pos);
    }



    public View getView(int position,View convertView, ViewGroup parent)
    {
        MyViewHolder viewHolder;
        if(convertView==null)
        {
            viewHolder = new MyViewHolder(convertView);
        }
        return null;
    }
}

class MyViewHolder extends ViewHolder
{
    TextView tv_title;
    TextView tv_in_out;
    TextView tv_date;
    TextView tv_cost;
    public MyViewHolder(View view)
    {
        super(view);

        tv_title = view.findViewById(R.id.tv_title);
        tv_in_out = view.findViewById(R.id.tv_in_out);
        tv_date = view.findViewById(R.id.tv_date);
        tv_cost = view.findViewById(R.id.tv_cost);
    }
}

holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
                public boolean onLongClick(View v) {
                    mOnItemClickListener.onItemLongClick(holder.itemView,pos);
                    return false;
                }
            });
        }
    }
    public int getItemCount() {
        return mList.size();
    }
    public Object getItem(int position){
        return position;
    }
    public long getItemId(int position){
        return position;
    }
    public void addData(CostBean costBean,int pos){
        mList.add(pos,costBean);
        notifyItemInserted(pos);
    }
    public void deleteData(int pos){
        mList.remove(pos);
        notifyItemRemoved(pos);
    }
    public View getView(int position,View convertView, ViewGroup parent){
        MyViewHolder viewHolder;
        if(convertView==null)viewHolder = new MyViewHolder(convertView);
        return null;
    }
}
class MyViewHolder extends ViewHolder{
    TextView tv_title;
    TextView tv_in_out;
    TextView tv_date;
    TextView tv_cost;
    public MyViewHolder(View view){
        super(view);
        tv_title = view.findViewById(R.id.tv_title);
        tv_in_out = view.findViewById(R.id.tv_in_out);
        tv_date = view.findViewById(R.id.tv_date);
        tv_cost = view.findViewById(R.id.tv_cost);
    }
}

      1. 记账页面相关

public class Account extends AppCompatActivity {
    //控件初始化 这里省略
    private boolean inorout = true;
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_account);
        btn_return = findViewById(R.id.btn_return);//控件赋值 这里以return键为例子省略其他
        if(checkIntentAvailable(getIntent())){
            if(getIntent().getIntExtra("chart",0)==3){
                et_money.setText(getIntent().getStringExtra("money"));
                btn_classify.setText(getIntent().getStringExtra("costTile"));
                inorout = getIntent().getBooleanExtra("costInOut",true);
            }
        }
        //按键监听
        btn_return.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                Intent intent = new Intent(Account.this, home_page.class);
                startActivity(intent);
            }
        });
        btn_classify.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                Intent intent = new Intent(Account.this, label.class);
                startActivityForResult(intent,2);
            }
        });
        btn_account_income.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                inorout = false;

//改变收入支出状态   改变按键背景颜色,代码同expend键}
        });
        btn_account_expend.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                inorout = true;
                btn_account_expend.setBackgroundColor(Color.parseColor("#ffffff"));
                btn_account_income.setBackgroundColor(Color.parseColor("#ececec"));
            }
        });

        btn_save.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String a= et_money.getText().toString();
                int i=Integer.parseInt(et_money.getText().toString());
                int j=getIntent().getIntExtra("chart",0);
                if(j==0)
                {
                    if(Integer.parseInt(et_money.getText().toString())==0||et_money.getText().equals(""))
                    {
                        Toast.makeText(Account.this, "请输入合法数值", Toast.LENGTH_SHORT).show();
                    }
                    else
                    {
                        Intent intent = new Intent(Account.this, home_page.class);
                        intent.putExtra("money",et_money.getText().toString());
                        //Toast.makeText(Account.this,btn_classify.getText().toString(),Toast.LENGTH_SHORT).show();
                        intent.putExtra("classify",btn_classify.getText().toString());//Title
                        intent.putExtra("inorout",inorout);
                        intent.putExtra("chart",0);
                        date = new Time();
                        date.setToNow();

                        intent.putExtra("Date",""+date.year +""+ date.month +""+ date.monthDay+"" + date.hour+"" + date.minute+"" + date.second);
                        intent.putExtra("Year",""+date.year);
                        intent.putExtra("Month",""+date.month+"");
                        intent.putExtra("Day",""+date.monthDay+"");
                        intent.putExtra("Hour",""+date.hour+"");
                        intent.putExtra("Minute",""+date.minute+"");
                        intent.putExtra("Second",""+date.second+"");

                        setResult(RESULT_OK,intent);

                        finish();
                        //出现了问题
                        //startActivity(intent);
                        //startActivityForResult(intent,1);

                    }
                }
                else if(j==1)
                {
                    Intent intent = new Intent(Account.this, home_page.class);
                    intent.putExtra("money",et_money.getText().toString());
                    //Toast.makeText(Account.this,btn_classify.getText().toString(),Toast.LENGTH_SHORT).show();
                    intent.putExtra("classify",btn_classify.getText().toString());//Title
                    intent.putExtra("inorout",inorout);
                    intent.putExtra("chart",1);
                    date = new Time();
                    date.setToNow();

                    intent.putExtra("Date",""+date.year +""+ date.month +""+ date.monthDay+"" + date.hour+"" + date.minute+"" + date.second);
                    intent.putExtra("Year",""+date.year);
                    intent.putExtra("Month",""+date.month+"");
                    intent.putExtra("Day",""+date.monthDay+"");
                    intent.putExtra("Hour",""+date.hour+"");
                    intent.putExtra("Minute",""+date.minute+"");
                    intent.putExtra("Second",""+date.second+"");
                    startActivity(intent);
                }
                else if(j==3)
                {
                    //更新数据
                    Intent intent = new Intent(Account.this, home_page.class);
                    intent.putExtra("money",et_money.getText().toString());
                    intent.putExtra("classify",btn_classify.getText().toString());//Title
                    intent.putExtra("inorout",inorout);
                    intent.putExtra("chart",2);
                    intent.putExtra("position",getIntent().getIntExtra("position",0));
                    startActivity(intent);
                }
            }
        });
    }


    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        //super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode){
            case 2:
                if(resultCode == RESULT_OK){
                    //Toast.makeText(Account.this,data.getStringExtra("classify"),Toast.LENGTH_SHORT).show();
                    btn_classify.setText(data.getStringExtra("classify"));
                }
                break;
            default:
                break;
        }
    }

    public boolean checkIntentAvailable(Intent intent){

        if (intent.resolveActivity(getPackageManager()) != null) {
            return true;

        } else {
            return  false;
        }

    }
}

 btn_save.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                String a= et_money.getText().toString();
                int i=Integer.parseInt(et_money.getText().toString());
                int j=getIntent().getIntExtra("chart",0);
                if(j==0)
{  if(Integer.parseInt(et_money.getText().toString())==0||et_money.getText().equals("")) {
             Toast.makeText(Account.this, "请输入合法数值", Toast.LENGTH_SHORT).show();
                    }
                    else{

//传数据回主页 从主页添加数据
                        Intent intent = new Intent(Account.this, home_page.class);
                        intent.putExtra("money",et_money.getText().toString());
                        intent.putExtra("classify",btn_classify.getText().toString());//Title
                        intent.putExtra("inorout",inorout);
                        intent.putExtra("chart",0);
                        date = new Time();
                        date.setToNow();
                        intent.putExtra("Date",""+date.year +""+ date.month +""+ date.monthDay+"" + date.hour+"" + date.minute+"" + date.second);
                        intent.putExtra("Year",""+date.year);
                        intent.putExtra("Month",""+date.month+"");
                        intent.putExtra("Day",""+date.monthDay+"");
                        intent.putExtra("Hour",""+date.hour+"");
                        intent.putExtra("Minute",""+date.minute+"");
                        intent.putExtra("Second",""+date.second+"");
                        setResult(RESULT_OK,intent);
                        finish();
                    }
                }
                else if(j==1)
                {
                    //同上 从图表页添加数据 省略
                    startActivity(intent);
                }
                else if(j==3)
                {
                    //传数据回主页 更新数据  同理 省略
                    startActivity(intent);
                }
            }
        });
    }


    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        //super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode){
            case 2:
                if(resultCode == RESULT_OK){
                    //Toast.makeText(Account.this,data.getStringExtra("classify"),Toast.LENGTH_SHORT).show();
                    btn_classify.setText(data.getStringExtra("classify"));
                }
                break;
            default:
                break;
        }
    }

    public boolean checkIntentAvailable(Intent intent){

        if (intent.resolveActivity(getPackageManager()) != null) {
            return true;

        } else {
            return  false;
        }

    }
}

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        switch (requestCode){
            case 2:
                if(resultCode == RESULT_OK){
                    btn_classify.setText(data.getStringExtra("classify"));
                }
                break;
            default:
                break;
        }
    }
    public boolean checkIntentAvailable(Intent intent){
        if (intent.resolveActivity(getPackageManager()) != null)  return true;
            else return  false;
    }
}

      1. 分类页显示以及隐藏页面相关

public void onShowItemClick(CostClassify bean)
{
    if(bean.isChecked()&&!sList.contains(bean))
    {
        sList.add(bean);
        if(sList.size()>1)
        {
            btn_edit.setVisibility(View.INVISIBLE);
        }
    }
    else if(!bean.isChecked()&&sList.contains(bean))
    {
        sList.remove(bean);
        if(sList.size()<=1)
        {
            btn_edit.setVisibility(View.VISIBLE);
        }
    }
}

//显示操作界面
private void showOpervate()
{
    btn_delete.setVisibility(View.VISIBLE);
    btn_redo.setVisibility(View.VISIBLE);
    btn_edit.setVisibility(View.VISIBLE);
    btn_add_item.setVisibility(View.GONE);

    btn_redo.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if(isShow){
                sList.clear();
                for(CostClassify bean:mList){
                    bean.setChecked(false);
                    bean.setShow(false);
                }
                mAdapter.notifyDataSetChanged();
                isShow = false;
                mRecyclerView.setLongClickable(true);
                dismissOperate();
            }
        }
    });

    btn_delete.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if(sList != null && sList.size()>0)
            {
                String[] temp = new String[50];
                int i = 0;
                for(CostClassify bean:sList)
                {
                    //Toast.makeText(label.this,bean.classifyName,Toast.LENGTH_SHORT).show();
                    temp[i] = bean.classifyName;
                    i++;
                }
                String[] temp1 = new String[1];
                for(int j=0;j<i;j++)
                {
                    temp1[0]=temp[j];
                    //Toast.makeText(label.this,temp1[j],Toast.LENGTH_SHORT).show();
                    mClassifybaseHelper.deleteData(temp1);
                }


                mList.removeAll(sList);
                sList.clear();
                for(CostClassify bean:mList){
                    bean.setChecked(false);
                    bean.setShow(false);
                }
                mAdapter.notifyDataSetChanged();
                isShow = false;
                mRecyclerView.setLongClickable(true);
                dismissOperate();
            }
            else{
                Toast.makeText(label.this,"请选择条目",Toast.LENGTH_SHORT).show();
            }
        }
    });

    btn_edit.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if(sList != null && sList.size()>0)
            {
                ShowLay(0);
            }
            else
            {
                Toast.makeText(label.this,"请选择item编辑",Toast.LENGTH_SHORT).show();
            }
        }
    });
}

private void ShowLay(int code)
{
    btn_add_item.setVisibility(View.GONE);
    if(code == 0)
    {
        btn_add_item.setVisibility(View.GONE);
        lay.setVisibility(View.VISIBLE);
        Animation animation = AnimationUtils.loadAnimation(this,R.anim.operate_in);
        lay.setAnimation(animation);
        btn_lay_return.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                DismissLay();
            }
        });

        btn_lay_yes.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //修改item名称----Upgrade数据
                CostClassify bean1 = sList.get(0);
                String[] temp = new String[1];
                temp[0] = bean1.classifyName;
                bean1.setClassifyName(et_classify.getText().toString());
                mClassifybaseHelper.upgradeCost(bean1,temp);

                if(isShow){
                    sList.clear();
                    for(CostClassify bean:mList){
                        bean.setChecked(false);
                        bean.setShow(false);
                    }
                    mAdapter.notifyDataSetChanged();
                    isShow = false;
                    mRecyclerView.setLongClickable(true);
                    dismissOperate();
                }
                DismissLay();
                mAdapter.notifyDataSetChanged();
                //btn_add_item.setVisibility(View.VISIBLE);
                //Toast.makeText(label.this,et_classify.getText(),Toast.LENGTH_SHORT).show();
            }
        });
    }
    else if(code == 1)
    {
        lay.setVisibility(View.VISIBLE);
        Animation animation = AnimationUtils.loadAnimation(this,R.anim.operate_in);
        lay.setAnimation(animation);
        btn_lay_return.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                DismissLay();
            }
        });

        btn_lay_yes.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //设定item名称----add数据
                CostClassify costClassify = new CostClassify();
                costClassify.setClassifyName(et_classify.getText().toString());
                costClassify.costInOut = "1";//可能修改
                costClassify.setShow(false);
                costClassify.setChecked(false);

                mClassifybaseHelper.insertCost(costClassify);
                mAdapter.addData(costClassify,0);
                DismissLay();
                mAdapter.notifyDataSetChanged();
                //Toast.makeText(label.this,et_classify.getText(),Toast.LENGTH_SHORT).show();
            }
        });
    }

}

private void DismissLay()
{
    lay.setVisibility(View.GONE);
    Animation animation = AnimationUtils.loadAnimation(this,R.anim.operate_out);
    lay.setAnimation(animation);
    btn_add_item.setVisibility(View.VISIBLE);
}

//隐藏操作界面
private void  dismissOperate()
{
    btn_add_item.setVisibility(View.VISIBLE);
    btn_delete.setVisibility(View.GONE);
    btn_redo.setVisibility(View.GONE);
    btn_edit.setVisibility(View.GONE);
}

分类页面的类别条列表显示与主页的账目列表显示操作一致,具体代码(ClassifyBaseHelper&ClassifyListAdapter&onCreate函数)略去,其他操作代码见下方文本框,具体内容见注释。

public void onShowItemClick(CostClassify bean)
{
    if(bean.isChecked()&&!sList.contains(bean))
    {
        sList.add(bean);
        if(sList.size()>1)
        {
            btn_edit.setVisibility(View.INVISIBLE);
        }
    }
    else if(!bean.isChecked()&&sList.contains(bean))
    {
        sList.remove(bean);
        if(sList.size()<=1)
        {
            btn_edit.setVisibility(View.VISIBLE);
        }
    }
}
//显示操作界面
private void showOpervate()
{
    btn_delete.setVisibility(View.VISIBLE);
    btn_redo.setVisibility(View.VISIBLE);
    btn_edit.setVisibility(View.VISIBLE);
    btn_add_item.setVisibility(View.GONE);

    btn_redo.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if(isShow){
                sList.clear();
                for(CostClassify bean:mList){
                    bean.setChecked(false);
                    bean.setShow(false);
                }
                mAdapter.notifyDataSetChanged();
                isShow = false;
                mRecyclerView.setLongClickable(true);
                dismissOperate();
            }
        }
    });

    btn_delete.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if(sList != null && sList.size()>0)
            {
                String[] temp = new String[50];
                int i = 0;
                for(CostClassify bean:sList)
                {
                    //Toast.makeText(label.this,bean.classifyName,Toast.LENGTH_SHORT).show();
                    temp[i] = bean.classifyName;
                    i++;
                }
                String[] temp1 = new String[1];
                for(int j=0;j<i;j++)
                {
                    temp1[0]=temp[j];
                    //Toast.makeText(label.this,temp1[j],Toast.LENGTH_SHORT).show();
                    mClassifybaseHelper.deleteData(temp1);
                }


                mList.removeAll(sList);
                sList.clear();
                for(CostClassify bean:mList){
                    bean.setChecked(false);
                    bean.setShow(false);
                }
                mAdapter.notifyDataSetChanged();
                isShow = false;
                mRecyclerView.setLongClickable(true);
                dismissOperate();
            }
            else{
                Toast.makeText(label.this,"请选择条目",Toast.LENGTH_SHORT).show();
            }
        }
    });

    btn_edit.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if(sList != null && sList.size()>0)
            {
                ShowLay(0);
            }
            else
            {
                Toast.makeText(label.this,"请选择item编辑",Toast.LENGTH_SHORT).show();
            }
        }
    });
}

private void ShowLay(int code)
{
    btn_add_item.setVisibility(View.GONE);
    if(code == 0)
    {
        btn_add_item.setVisibility(View.GONE);
        lay.setVisibility(View.VISIBLE);
        Animation animation = AnimationUtils.loadAnimation(this,R.anim.operate_in);
        lay.setAnimation(animation);
        btn_lay_return.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                DismissLay();
            }
        });

        btn_lay_yes.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //修改item名称----Upgrade数据
                CostClassify bean1 = sList.get(0);
                String[] temp = new String[1];
                temp[0] = bean1.classifyName;
                bean1.setClassifyName(et_classify.getText().toString());
                mClassifybaseHelper.upgradeCost(bean1,temp);

                if(isShow){
                    sList.clear();
                    for(CostClassify bean:mList){
                        bean.setChecked(false);
                        bean.setShow(false);
                    }
                    mAdapter.notifyDataSetChanged();
                    isShow = false;
                    mRecyclerView.setLongClickable(true);
                    dismissOperate();
                }
                DismissLay();
                mAdapter.notifyDataSetChanged();
                //btn_add_item.setVisibility(View.VISIBLE);
                //Toast.makeText(label.this,et_classify.getText(),Toast.LENGTH_SHORT).show();
            }
        });
    }
    else if(code == 1)
    {
        lay.setVisibility(View.VISIBLE);
        Animation animation = AnimationUtils.loadAnimation(this,R.anim.operate_in);
        lay.setAnimation(animation);
        btn_lay_return.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                DismissLay();
            }
        });

        btn_lay_yes.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //设定item名称----add数据
                CostClassify costClassify = new CostClassify();
                costClassify.setClassifyName(et_classify.getText().toString());
                costClassify.costInOut = "1";//可能修改
                costClassify.setShow(false);
                costClassify.setChecked(false);

                mClassifybaseHelper.insertCost(costClassify);
                mAdapter.addData(costClassify,0);
                DismissLay();
                mAdapter.notifyDataSetChanged();
                //Toast.makeText(label.this,et_classify.getText(),Toast.LENGTH_SHORT).show();
            }
        });
    }

}

private void DismissLay()
{
    lay.setVisibility(View.GONE);
    Animation animation = AnimationUtils.loadAnimation(this,R.anim.operate_out);
    lay.setAnimation(animation);
    btn_add_item.setVisibility(View.VISIBLE);
}

//隐藏操作界面
private void  dismissOperate()
{
    btn_add_item.setVisibility(View.VISIBLE);
    btn_delete.setVisibility(View.GONE);
    btn_redo.setVisibility(View.GONE);
    btn_edit.setVisibility(View.GONE);
}

btn_delete.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            if(sList != null && sList.size()>0){
                String[] temp = new String[50];
                int i = 0;
                for(CostClassify bean:sList) {
                    temp[i] = bean.classifyName;
                    i++;
                }
                String[] temp1 = new String[1];
                for(int j=0;j<i;j++) {
                    temp1[0]=temp[j];
                    mClassifybaseHelper.deleteData(temp1);
                }
                mList.removeAll(sList);
                sList.clear();
                for(CostClassify bean:mList){
                    bean.setChecked(false);
                    bean.setShow(false);
                }
                mAdapter.notifyDataSetChanged();
                isShow = false;
                mRecyclerView.setLongClickable(true);
                dismissOperate();
            }
            else{
                Toast.makeText(label.this,"请选择条目",Toast.LENGTH_SHORT).show();
            }
        }
    });
    btn_edit.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            if(sList != null && sList.size()>0){
                ShowLay(0);
            }
            else
            {
                Toast.makeText(label.this,"请选择item编辑",Toast.LENGTH_SHORT).show();
            }
        }
    });
}

private void ShowLay(int code)
{
    btn_add_item.setVisibility(View.GONE);
    if(code == 0)
    {
        btn_add_item.setVisibility(View.GONE);
        lay.setVisibility(View.VISIBLE);
        Animation animation = AnimationUtils.loadAnimation(this,R.anim.operate_in);
        lay.setAnimation(animation);
        btn_lay_return.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                DismissLay();
            }
        });

        btn_lay_yes.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //修改item名称----Upgrade数据
                CostClassify bean1 = sList.get(0);
                String[] temp = new String[1];
                temp[0] = bean1.classifyName;
                bean1.setClassifyName(et_classify.getText().toString());
                mClassifybaseHelper.upgradeCost(bean1,temp);

                if(isShow){
                    sList.clear();
                    for(CostClassify bean:mList){
                        bean.setChecked(false);
                        bean.setShow(false);
                    }
                    mAdapter.notifyDataSetChanged();
                    isShow = false;
                    mRecyclerView.setLongClickable(true);
                    dismissOperate();
                }
                DismissLay();
                mAdapter.notifyDataSetChanged();
                //btn_add_item.setVisibility(View.VISIBLE);
                //Toast.makeText(label.this,et_classify.getText(),Toast.LENGTH_SHORT).show();
            }
        });
    }
    else if(code == 1)
    {
        lay.setVisibility(View.VISIBLE);
        Animation animation = AnimationUtils.loadAnimation(this,R.anim.operate_in);
        lay.setAnimation(animation);
        btn_lay_return.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                DismissLay();
            }
        });

        btn_lay_yes.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //设定item名称----add数据
                CostClassify costClassify = new CostClassify();
                costClassify.setClassifyName(et_classify.getText().toString());
                costClassify.costInOut = "1";//可能修改
                costClassify.setShow(false);
                costClassify.setChecked(false);

                mClassifybaseHelper.insertCost(costClassify);
                mAdapter.addData(costClassify,0);
                DismissLay();
                mAdapter.notifyDataSetChanged();
                //Toast.makeText(label.this,et_classify.getText(),Toast.LENGTH_SHORT).show();
            }
        });
    }

}

private void DismissLay()
{
    lay.setVisibility(View.GONE);
    Animation animation = AnimationUtils.loadAnimation(this,R.anim.operate_out);
    lay.setAnimation(animation);
    btn_add_item.setVisibility(View.VISIBLE);
}

//隐藏操作界面
private void  dismissOperate()
{
    btn_add_item.setVisibility(View.VISIBLE);
    btn_delete.setVisibility(View.GONE);
    btn_redo.setVisibility(View.GONE);
    btn_edit.setVisibility(View.GONE);
}

private void ShowLay(int code)
{
    btn_add_item.setVisibility(View.GONE);
    if(code == 0)
    {
        btn_add_item.setVisibility(View.GONE);
        lay.setVisibility(View.VISIBLE);
        Animation animation = AnimationUtils.loadAnimation(this,R.anim.operate_in);
        lay.setAnimation(animation);
        btn_lay_return.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                DismissLay();
            }
        });
        btn_lay_yes.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //修改item名称----Upgrade数据
                CostClassify bean1 = sList.get(0);
                String[] temp = new String[1];
                temp[0] = bean1.classifyName;
                bean1.setClassifyName(et_classify.getText().toString());
                mClassifybaseHelper.upgradeCost(bean1,temp);

                if(isShow){
                    sList.clear();
                    for(CostClassify bean:mList){
                        bean.setChecked(false);
                        bean.setShow(false);
                    }
                    mAdapter.notifyDataSetChanged();
                    isShow = false;
                    mRecyclerView.setLongClickable(true);
                    dismissOperate();
                }
                DismissLay();
                mAdapter.notifyDataSetChanged();
            }
        });
    }
    else if(code == 1)
    {
        lay.setVisibility(View.VISIBLE);
        Animation animation = AnimationUtils.loadAnimation(this,R.anim.operate_in);
        lay.setAnimation(animation);
        btn_lay_return.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                DismissLay();
            }
        });

        btn_lay_yes.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //设定item名称----add数据
                CostClassify costClassify = new CostClassify();
                costClassify.setClassifyName(et_classify.getText().toString());
                costClassify.costInOut = "1";//可能修改
                costClassify.setShow(false);
                costClassify.setChecked(false);

                mClassifybaseHelper.insertCost(costClassify);
                mAdapter.addData(costClassify,0);
                DismissLay();
                mAdapter.notifyDataSetChanged();
                //Toast.makeText(label.this,et_classify.getText(),Toast.LENGTH_SHORT).show();
            }
        });
    }

}

private void DismissLay()
{
    lay.setVisibility(View.GONE);
    Animation animation = AnimationUtils.loadAnimation(this,R.anim.operate_out);
    lay.setAnimation(animation);
    btn_add_item.setVisibility(View.VISIBLE);
}

//隐藏操作界面
private void  dismissOperate()
{
    btn_add_item.setVisibility(View.VISIBLE);
    btn_delete.setVisibility(View.GONE);
    btn_redo.setVisibility(View.GONE);
    btn_edit.setVisibility(View.GONE);
}

    Animation animation = AnimationUtils.loadAnimation(this,R.anim.operate_in);
        lay.setAnimation(animation);
        btn_lay_return.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                DismissLay();
            }
        });
        btn_lay_yes.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                //设定item名称----add数据
                CostClassify costClassify = new CostClassify();
                costClassify.setClassifyName(et_classify.getText().toString());
                costClassify.costInOut = "1";//可能修改
                costClassify.setShow(false);
                costClassify.setChecked(false);
                mClassifybaseHelper.insertCost(costClassify);
                mAdapter.addData(costClassify,0);
                DismissLay();
                mAdapter.notifyDataSetChanged();
            }
        });
    }
}
private void DismissLay()
{
    lay.setVisibility(View.GONE);
    Animation animation = AnimationUtils.loadAnimation(this,R.anim.operate_out);
    lay.setAnimation(animation);
    btn_add_item.setVisibility(View.VISIBLE);
}
//隐藏操作界面
private void  dismissOperate()
{
    btn_add_item.setVisibility(View.VISIBLE);
    btn_delete.setVisibility(View.GONE);
    btn_redo.setVisibility(View.GONE);
    btn_edit.setVisibility(View.GONE);
}

上述代码中长按被隐藏的界面显示之后的效果如下:

 

选择编辑按钮之后从屏幕下方滑出的编辑框效果如下:

 

该页面部分涉及到的动画代码如下:

//operate_in.xml
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromYDelta="100%"
    android:toYDelta="0"
    android:duration="500">>
</set>

//operate_out.xml

<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromYDelta="0"
    android:toYDelta="100%"
    android:duration="500">
</set>

      1. 分类页数据库操作相关

与主页DatabaseHelper操作类&RecyclerView.Adapter操作类基本一致,根据代码同理进行小部分修改即可,这里略去。

      1. 图表页相关

这里涉及到了


 

  1. 测试
    1. 测试内容及遇到的问题&解决方法

问题1:注释掉清空全部数据库的测试代码后,进行页面跳转之后再返回读取数据库数据的recylerView界面时发现之前插入的数据均未显示,以及之前删除的数据也再次恢复(设置了初始数据的情况)才发现数据库读取出现了问题,不然就是根本没有写进数据库。

解决方法:在编写Classify页面的项目添加时发现成功插入了数据库,并且经过多个页面跳转之后仍然可以正常读取,从而返回去检查home_page的数据库插入问题,经过对比发现在插入数据库时设定的主键id没有用代码插入,所以数据库插入出现了问题,经过修改数据库的创建代码之后(即创建数据库放弃id这个数据项,设置新主键)可以正确读取数据库。

问题2&解决方法:在解决问题1的时候遇到了另一个问题,一开始的解决方法是设定一个新的int数据来给id赋值,在插入数据时进行id++操作。这样插入数据是没有问题的,后来发现在重新启动app的情况下id会重新从0开始自增。导致主键重复,数据插入失败。所以在了解系统在创建表的时候会自动加入一个rowid数据项之后选择了放弃id这个数据项。

问题3:也是在解决问题1的时候遇到的问题,在确定放弃id这个数据项之后,我选择了直接在原来创建数据库的代码上删除了创建id数据项的语句。之后启动项目崩溃。检查之后发现由于原来已经创建了表和数据库,修改代码后再次创建了相同表名的表导致表重复无法重新创表。

解决方法:修改了表名也在数据库中删除了原表。

问题4:界面跳转问题,Finish()方法的缺陷;在Account界面利用startActivity()跳转到Classify界面并且选择完item返回Account界面时一开始选择的也是startActivity()跳转所以导致Account界面原本打算跳转到home_page的finish()方法跳转到了Classify界面

解决方法:将Classify跳转回Account界面的方法修改成了finish()方法则这样不会修改Account界面的上一个界面是home_page界面

问题5:初始化账目list收入支出金额text颜色显示问题,想要达到的效果是收入金额Text红色显示,支出金额Text黑色显示。但是实现的效果是,在插入金额时,list自动更新时是达到了想要的效果,但是重开app后,所有的金额都会变成布局文件中设定的初始颜色。再插入还是会有红黑之分。

解决办法:在寻求了同学的帮助下,不断排查了代码发现了问题;在改变Text颜色的代码之前进行的判断字符串是”收入”还是”支出”用的是”==”判断,在修改成equal之后该bug被解决。引起这个的原因主要是在判断的时候读取的字符串不是从数据库读取的,而是直接从布局中读取的,尽管显示出来有支出收入之分,但是读取时读的都是布局初始化的内个字段,以本项目为例,布局文件始终以支出为初始显示Text所以重开app之后所有收入支出字段的颜色又会被统一成黑色。

问题6:若第一次饼图设置pieValue数据分别为20,30,50;则控件默认以后都是数据之和为100时饼图才会全部显示,否则,若重新设置pieValue值为20,30;则会显示半圆。

解决方法:将pieValue按百分比设置,使之和一直为1即可,如上可改写为0.2,0.3,0.5;第二次重新设置0.4,0.6即可,故我们写了一个计算百分比的函数,每次要从数据库读取数据显示在饼图上时,先把读取到的数据计算出各自的百分比,再显示到饼图上。

问题7&解决方法:打开新项目后,R文件无法识别将build.gradle中的classpath改为自己相应的版本

    1. 可优化方案
  1. 可以在页面跳转之前就插入数据进数据库,就不需要跳转页面传数据再插入数据库这么麻烦。
  2. 可以将布局文件的页头页尾等重复部分封装再使用,效率以及方便程度都大大提升
  3. UI方面的美观程度还可以有所提升
  4. 账目页和图表页可以做成一个界面,点击按钮只切换中间部分

但是考虑到这些优化方案的时候本项目完成度已经比较高了所以避免后续出现新的bug,该优化方案暂时只是提出,不做实质性修改。

    1. 未解决问题&部分修改

由于Classify(分类)界面涉及到的支出收入按钮在返回Account界面时仍然有一个选择支出收入的界面,以至于要求用户选择了支出的分类之后返回account界面后不允许选择支出的按钮,涉及到的代码内容简单但是繁琐,所以本项目选择丢弃Classify界面的收入支出按钮。

账目主页的listView嵌套未实现(即在月份之间再区分日期)

  1. 难点分析
    1. 数据库的操作代码编写

本项目的重点,数据库中表的创建以及其他功能的实现非常容易出错,而且Android studio不会在因为数据库的操作错误而提示出具体的错误信息,app会直接终止运行,所以很难自己找出bug在哪。

    1. RecyclerView的显示和布局以及item样式设置

这一点主要是针对以前从未接触过list以及从数据库读取显示的新手,第一次接触理解和操作起来都比较难,很容易在初始化列表以及读取item的时候出错。

    1. 隐藏显示新界面及动画的使用

由于动画的使用课堂涉及比较少,所以只能通过看博客以及自我理解来使用,很容易连动画xml文件如何创建都不知道。隐藏和显示界面需要自定义函数来实现,所以要判断的地方比较多,很容易出现判断不足或者显示和数据更改错误或未更改问题。

    1. 复选框的相关操作

复选框涉及到界面的显示以及按钮的显示,所以要在相关界面进行不断的判断,并且经常要读取被选项的相关数据,对于之前未接触过复选框相关操作的新手,容易忽略一些地方的判断,复选框的实现以及操作会显得比较复杂和繁琐。

    1. 图表的统计显示

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/49127.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

用友U8二次开发之登录

首先引用U8的登录DLL&#xff1a; 然后是调用U8的登录UI&#xff1a; UFSoft.U8.Framework.Login.UI.clsLogin U_Login new UFSoft.U8.Framework.Login.UI.clsLogin();U_Login.login("DP")其中DP是门户子系统的代码&#xff0c;如果不调用U8的业务系统功能&#xff…

基于android的记账APP大作业项目

基于android的记账APP 一 项目介绍 由于日常生活中,有很多月光一族的人们&#xff0c;他们往往不知不觉&#xff0c;觉得钱用的差不多了。而且最后回想起来&#xff0c;还不知道钱用到哪些地方了。所以开发此软件的目的&#xff0c;就是为了解决这样的问题&#xff0c;从软件…

【安卓开发】简单记账app功能实现开发-期末大作业个人总结

说在前面&#xff1a; 由于这一次的大作业涉及到的代码部分过于长&#xff0c;所以博客里不放相关代码&#xff1b; 工程&apk&记账app原型&素材资源链接&#xff1a;https://download.csdn.net/download/white2333/11234105 配套文档目录预览&资源链接&…

管家婆软件创建账套提示:创建账套失败

我们在安装完管家婆软件后&#xff0c;在创建账套的时&#xff0c;可能会碰到这个错误&#xff1a;创建账套失败&#xff01;这个报错要怎么去解决呢&#xff1f; 问题原因1&#xff1a;这个提示一般是管家婆软件安装目录比较深&#xff0c;就比如A文件夹里面有个A1的文件夹&am…

【T+】将查询账套更换成可以业务操作的正式版账套

【问题描述】 在使用畅捷通T软件过程中&#xff0c; 由于某些原因&#xff0c;将已使用的账套设置成【查询版】&#xff0c;并且根据软件提示&#xff0c;设置后该账套只能查询使用&#xff0c;不可以进行业务操作。 并且【查询】账套不支持反操作。 设置成查询版后&#xff0c…

SAP中使用LSMW批量导入总账科目

遗留数据迁移平台&#xff0c;可以导入主数据&#xff1a;科目、资产主数据、物料主数据、供应商、客户主数据、成本中心、内部订单数据。。。。 FSP0 FSS0 分层导入&#xff1a;适合集团和分公司分别维护科目主数据&#xff0c;集团和公司自行维护科目主数据 FS00集中导入&a…

SAP系统 会计科目主数据详解

会计科目&#xff08;主数据&#xff09;概述&#xff1a; 每个公司代码均指定一个总帐的科目表。此科目表在配置中分配到公司代码&#xff0c;作为其运营科目表 每个总帐都是根据科目表建立的。所有总帐科目的定义均以有序形式包含在科目表内。定义主要由科目编号、科目名称…

工资管理系统(附源码,直接复制就可以跑起来)

分享一个Java Application的工资系统。 运行界面如下&#xff1a; 其他分类专栏也有一些其他的Java Web系统 点击分类专栏介绍查看 直接创建如下的5个Java类文件。 1.项目工程 2.CommonEmployee类 package study;import java.util.*;public class TestEMD {/*** len代表数组的…

如何快速为子公司创建SAP财务账套的操作步骤

相对来说在SAP上配置一家子公司比从0开始创建创建一家公司可以节省很多步骤&#xff0c;因为子公司的很多配置&#xff08;如科目表&#xff0c;科目&#xff0c;折旧表&#xff0c;折旧代码等&#xff09;可以沿用母公司的。本文就简单介绍一下创建子公司财务账套的配置步骤.只…

【U8+】用友U8+对账不平案例及方法总结

【问题需求】 在使用用友U8软件过程中&#xff0c;由于软件涉及到多方面的对账。 所以经常会遇到期初或结账时对账不平。 【经验分享】 在众多对账中&#xff0c; 只有当【总账上下级】&#xff08;即&#xff1a;总账与明细账对账&#xff09;不平的时候&#xff0c; 软件才…

Android课设——理财小助手

一&#xff1a;app介绍 理财小助手是一款利用Android studio软件实现的APP&#xff0c;可以录入每天的消费项目以及消费金额&#xff0c;同时也可以查找消费记录、统计消费总额。我用到的Android studio版本如下&#xff1a; 二、模块设计 下面是我实现的一些模块&#xff1a; …

SAP总账科目增强写入客商(BAPI导入)

正常SAP总账科目的客商是无法直接导入的&#xff0c;增强试了一下&#xff0c;发现有点问题。 正常凭证增强只要在增强结构增加字段字段后&#xff0c;在BAPI的 EXTENSION2 里赋值就行&#xff0c;这次不好用了。 跟踪了下标准程序&#xff0c;发现被这个地方的值覆盖了。 …

基于Android studio个人财务记账管理系统

1.注册登录模块&#xff1a;完成对用户的注册&#xff0c;以及用户登录应用的功能,对密码要求至少8位&#xff0c;可以识别出账号是否注册过&#xff0c;登录之后有欢迎词。 2.个人信息模块&#xff1a;完成对用户对自己的用户名修改&#xff0c;头像进行设置和修改的功能&…

一加七语音唤醒_一加8t有语音助手吗

一加手机本来没有语音助手&#xff0c;不过一加手机从氢OS 10.0开始支持语音助手小布&#xff0c;那么最新发布的一加8t有语音助手吗?下面一起来看看吧~ 品牌型号&#xff1a;一加8t 系统版本&#xff1a;氢OS 10.0 一加8t有语音助手吗? 一加8t手机有语音助手&#xff0c;它有…

纪念胡包钢研究员

昨日&#xff08;8月22日&#xff09;上午我在公众号发了一篇关于开源的文章&#xff0c;照例通过微信发给胡包钢老师&#xff0c;希望他给点建议&#xff0c;但未获回复。下午我从其他途径得知胡包钢老师在8月22日早上因病去世&#xff0c;犹如晴天霹雳。 胡包钢老师一直是我尊…

微软首席开发大师 查尔斯-西蒙尼

微软首席开发大师 查尔斯-西蒙尼 分类&#xff1a; 软件英雄 2011-11-12 14:33 118人阅读 评论(0) 收藏 举报 微软首席开发大师 查尔斯-西蒙尼 分类&#xff1a; 人物漫谈 2005-10-02 15:24 9921人阅读 评论(23) 收藏 举报 查尔斯—西蒙尼&#xff08;Charles Simonyi&am…

微软曾经的二号人物永远地离开了

参加 2018 AI开发者大会&#xff0c;请点击 大会官网 他是一位发明家、投资者、考古学家和慈善家&#xff0c;“他对微软做出的不可或缺的贡献”会让人们永远铭记。 据外媒 CNBC 今日早间报道&#xff0c;微软联合创始人之一保罗艾伦&#xff08;Paul Allen&#xff09;于当地时…

特斯拉:为什么我这么牛逼?

结束了旅行之后&#xff0c;父亲专门为我挑选了历史悠久、名声在外的奥地利斯蒂里亚省格劳姆茨市的理工学校&#xff0c;把我送到那里读书。我终于实现了自己期待已久的心愿&#xff0c;开始正式学习工程技术&#xff0c;并且获得了足够的资金支持。我下定决心&#xff0c;一定…

华为丁耘突发疾病去世

昨天的事情&#xff0c;看到了很多人发的朋友圈。 前阵子突发去世的是旷视科技的孙剑先生&#xff0c;相比于丁耘先生&#xff0c;孙剑博士在技术领域知名度更大&#xff0c;因为孙剑博士的事情&#xff0c;我问了一些圈内的朋友&#xff0c;很多机器学习上的技术文章大多数引用…

昔日“东方神童”逝世,4岁读完初中课程,17岁中科院硕博连读,网友:湖南华容的传说...

杨净 发自 凹非寺量子位 报道 | 公众号 QbitAI 他4岁读完初中&#xff0c;我4岁刚不尿裤子。 他8岁进入重点高中&#xff0c;我8岁刚学加减法。 他13岁考入大学&#xff0c;我13岁还和同学打架。 他17岁硕博连读&#xff0c;我17岁忙着早恋。 …… 最近&#xff0c;天涯论坛上一…