【家庭记账本】Android开发(提交稿件)

  本次更新了自己的app,这次更新是上交作业,还有很多预想功能没有实现,有时间还会继续更新。一些界面跟上次的没有差别,这里只展示新增的东西。

  改进后的app使用了Fragment+底部导航栏;ListView显示数据;选择日期上使用了DatePickerDialog;最后增设了“删除数据”按钮,由于在限定时间内没有完成按条件模糊删除功能,所以这里删除是将数据库所有数据删除。接下来进行展示:

首先是添加数据界面的选择日期:

 

 

代码如下:

 1 @Override
 2     public void onClick(View view){
 3         switch (view.getId()){
 4             //点击日期的编辑框,弹出选择日期的界面
 5             case R.id.amdate:
 6                 Calendar cal=Calendar.getInstance();
 7                 //month要+1
 8                 DatePickerDialog date=new DatePickerDialog(AddMes.this, new DatePickerDialog.OnDateSetListener() {
 9                     @Override
10                     public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) {
11                         //选择后显示
12                         amdate.setText(year+"年"+(month+1)+"月"+dayOfMonth+"日");
13                     }
14                 },cal.get(Calendar.YEAR),cal.get(Calendar.MONTH),cal.get(Calendar.DAY_OF_MONTH)+1);
15                 date.show();
16                 break;
17             case R.id.amcreate:
18                 user_str=amuser.getText().toString();
19                 name_str=amname.getText().toString();
20                 money_str=amoney.getText().toString()+"元";
21                 date_str=amdate.getText().toString();
22 
23                 ContentValues values=new ContentValues();
24                 values.put("musername",user_str);
25                 values.put("name",name_str);
26                 values.put("money",money_str);
27                 values.put("date",date_str);
28                 values.put("inout",inout_str);
29                 sqLiteDatabase.insert("message",null,values);
30 
31                 finish();
32                 break;
33                 default:
34                     break;
35         }
36     }

Android中的DatePickerDialog调用十分方便,编写时需要注意其中的month月份数要+1。为了弹出该选择界面,这里选择将日期的EditView框设置点击的监听事件。

 

接下来是Fragment+底部导航栏,这里写了很多文件。这些是Fragment的java文件,我一共设置了三个选项

 

 详细文件:

FragmentA(只显示收入的账单)

 1 package com.example.vacation;
 2 
 3 import androidx.appcompat.app.AppCompatActivity;
 4 import androidx.fragment.app.Fragment;
 5 
 6 import android.database.Cursor;
 7 import android.database.sqlite.SQLiteDatabase;
 8 import android.os.Bundle;
 9 import android.view.LayoutInflater;
10 import android.view.View;
11 import android.view.ViewGroup;
12 import android.widget.ListView;
13 import android.widget.TextView;
14 
15 import java.util.ArrayList;
16 
17 public class FragmentA extends Fragment {
18     private static String Aname;
19     private TextView atv_id,atv_name,atv_money,atv_date,atv_inout;
20     private ListView lv_mes1;
21     private SQLiteDatabase db;
22     private DBUser helper;
23     private ArrayList<MesInfo> listData;
24     private MesAdapter adapter;
25     public FragmentA(){
26     }
27     @Override
28    public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState){
29         return inflater.inflate(R.layout.activity_fragment,container,false);
30     }
31     public void onActivityCreated(Bundle savedInstanceState){
32         super.onActivityCreated(savedInstanceState);
33         Bundle bundle1=this.getArguments();
34         if(bundle1!=null){
35             Aname=bundle1.getString("Auser");
36         }
37         atv_name=(TextView)getActivity().findViewById(R.id.tv_name);
38         atv_money=(TextView)getActivity().findViewById(R.id.tv_money);
39         atv_date=(TextView)getActivity().findViewById(R.id.tv_date);
40         atv_inout=(TextView)getActivity().findViewById(R.id.tv_inout);
41         lv_mes1=(ListView)getActivity().findViewById(R.id.lv_mes1);
42         listData=new ArrayList<MesInfo>();
43         helper=new DBUser(getActivity(),"user_db",null,1);
44         db=helper.getWritableDatabase();
45 
46         String sql="select * from message where musername=? and inout='收入'";
47         Cursor cursor=db.rawQuery(sql,new String[]{Aname});
48         while(cursor.moveToNext()){
49             MesInfo mes=new MesInfo();
50             mes.setName(cursor.getString(cursor.getColumnIndex("name")));
51             mes.setMoney(cursor.getString(cursor.getColumnIndex("money")));
52             mes.setDate(cursor.getString(cursor.getColumnIndex("date")));
53             mes.setInout(cursor.getString(cursor.getColumnIndex("inout")));
54             listData.add(mes);
55         }
56         adapter=new MesAdapter(this.getActivity(),listData);
57         lv_mes1.setAdapter(adapter);
58         adapter.notifyDataSetChanged();
59     }
60 }

粘贴时忘了代码注释(汗)

FragmentB(只显示支出的账单)

 1 package com.example.vacation;
 2 
 3 import androidx.appcompat.app.AppCompatActivity;
 4 import androidx.fragment.app.Fragment;
 5 
 6 import android.database.Cursor;
 7 import android.database.sqlite.SQLiteDatabase;
 8 import android.os.Bundle;
 9 import android.view.LayoutInflater;
10 import android.view.View;
11 import android.view.ViewGroup;
12 import android.widget.ListView;
13 import android.widget.TextView;
14 
15 import java.util.ArrayList;
16 
17 public class FragmentB extends Fragment {
18     //声明控件
19     private static String Bname;
20     private TextView btv_id,btv_name,btv_money,btv_date,btv_inout;
21     private ListView lv_mes2;
22     private SQLiteDatabase db;
23     private DBUser helper;
24     private ArrayList<MesInfo> listData;
25     private MesAdapter adapter;
26     public FragmentB(){
27 
28     }
29     //连接对应fragment界面
30     @Override
31     public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState){
32         return inflater.inflate(R.layout.activity_fragment_b,container,false);
33     }
34     //编写事件
35     public void onActivityCreated(Bundle savedInstanceState){
36         super.onActivityCreated(savedInstanceState);
37         //接收从Activity传过来的值
38         Bundle bundle2=this.getArguments();
39         if(bundle2!=null){
40             Bname=bundle2.getString("Buser");
41         }
42         //运用ListView进行遍历数据库并输出
43         btv_name=(TextView)getActivity().findViewById(R.id.tv_name);
44         btv_money=(TextView)getActivity().findViewById(R.id.tv_money);
45         btv_date=(TextView)getActivity().findViewById(R.id.tv_date);
46         btv_inout=(TextView)getActivity().findViewById(R.id.tv_inout);
47         lv_mes2=(ListView)getActivity().findViewById(R.id.lv_mes2);
48         listData=new ArrayList<MesInfo>();
49         helper=new DBUser(getActivity(),"user_db",null,1);
50         db=helper.getWritableDatabase();
51 
52         String sql="select * from message where musername=? and inout='支出'";
53         Cursor cursor=db.rawQuery(sql,new String[]{Bname});
54         while(cursor.moveToNext()){
55             MesInfo mes=new MesInfo();
56             mes.setName(cursor.getString(cursor.getColumnIndex("name")));
57             mes.setMoney(cursor.getString(cursor.getColumnIndex("money")));
58             mes.setDate(cursor.getString(cursor.getColumnIndex("date")));
59             mes.setInout(cursor.getString(cursor.getColumnIndex("inout")));
60             listData.add(mes);
61         }
62         adapter=new MesAdapter(this.getActivity(),listData);
63         lv_mes2.setAdapter(adapter);
64         adapter.notifyDataSetChanged();
65     }
66 }

 

FragmentC(显示所有账单)

 1 import androidx.fragment.app.Fragment;
 2 
 3 import android.content.Intent;
 4 import android.database.Cursor;
 5 import android.database.sqlite.SQLiteDatabase;
 6 import android.os.Bundle;
 7 import android.view.LayoutInflater;
 8 import android.view.View;
 9 import android.view.ViewGroup;
10 import android.widget.ListView;
11 import android.widget.TextView;
12 
13 import java.util.ArrayList;
14 
15 public class FragmentC extends Fragment {
16     //声明控件
17     private static String Cname;
18     private TextView ctv_id,ctv_name,ctv_money,ctv_date,ctv_inout;
19     private ListView lv_mes3;
20     private SQLiteDatabase db;
21     private DBUser helper;
22     private ArrayList<MesInfo> listData;
23     private MesAdapter adapter;
24 
25     public FragmentC(){
26     }
27     @Override
28     public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState){
29         return inflater.inflate(R.layout.activity_fragment_c,container,false);
30     }
31     //事件
32     @Override
33     public void onActivityCreated(Bundle savedInstanceState){
34         super.onActivityCreated(savedInstanceState);
35         Bundle bundle3=this.getArguments();
36         if(bundle3!=null){
37          Cname=bundle3.getString("Cuser");
38         }
39         ctv_name=(TextView)getActivity().findViewById(R.id.tv_name);
40         ctv_money=(TextView)getActivity().findViewById(R.id.tv_money);
41         ctv_date=(TextView)getActivity().findViewById(R.id.tv_date);
42         ctv_inout=(TextView)getActivity().findViewById(R.id.tv_inout);
43         lv_mes3=(ListView)getActivity().findViewById(R.id.lv_mes3);
44         listData=new ArrayList<MesInfo>();
45         helper=new DBUser(getActivity(),"user_db",null,1);
46         db=helper.getWritableDatabase();
47 
48         String sql="select * from message where musername=?";
49         Cursor cursor=db.rawQuery(sql,new String[]{Cname});
50         while(cursor.moveToNext()){
51             MesInfo mes=new MesInfo();
52             mes.setName(cursor.getString(cursor.getColumnIndex("name")));
53             mes.setMoney(cursor.getString(cursor.getColumnIndex("money")));
54             mes.setDate(cursor.getString(cursor.getColumnIndex("date")));
55             mes.setInout(cursor.getString(cursor.getColumnIndex("inout")));
56             listData.add(mes);
57         }
58         adapter=new MesAdapter(this.getActivity(),listData);
59         lv_mes3.setAdapter(adapter);
60         adapter.notifyDataSetChanged();
61     }
62 }

fragment需要嵌入activity去实现,下面给出相关activity的代码

 1 package com.example.vacation;
 2 
 3 import androidx.appcompat.app.AppCompatActivity;
 4 import androidx.fragment.app.FragmentManager;
 5 import androidx.fragment.app.FragmentTransaction;
 6 
 7 import android.content.Intent;
 8 import android.os.Bundle;
 9 import android.view.View;
10 import android.widget.RelativeLayout;
11 import android.widget.TextView;
12 
13 public class Search extends AppCompatActivity implements View.OnClickListener{
14 
15     //声明,注意RelativeLayout也需要声明,此处用来嵌入fragment
16     private FragmentManager fragmentManager;
17     private RelativeLayout content;
18     private TextView item1,item2,item3;
19     private static String thename;
20 
21     @Override
22     protected void onCreate(Bundle savedInstanceState) {
23         super.onCreate(savedInstanceState);
24         setContentView(R.layout.activity_search);
25 
26         content=(RelativeLayout)findViewById(R.id.content);
27         item1=(TextView)findViewById(R.id.item1);
28         item2=(TextView)findViewById(R.id.item2);
29         item3=(TextView)findViewById(R.id.item3);
30 
31         fragmentManager=getSupportFragmentManager();
32 
33         item1.setOnClickListener(this);
34         item2.setOnClickListener(this);
35         item3.setOnClickListener(this);
36 
37         Intent intentdata=getIntent();
38         String catchuser=intentdata.getStringExtra("buser");
39         if(catchuser!=null){
40             thename=catchuser;
41         }
42     }
43 
44     //点击不同按钮跳转至不同的fragment
45     @Override
46     public void onClick(View v) {
47         switch(v.getId()){
48             //Activity向Fragment传值,使用Bundle
49             case R.id.item1:
50                 FragmentA fragmentA=new FragmentA();
51                 Bundle bundle1=new Bundle();
52                 bundle1.putString("Auser",thename);
53                 fragmentA.setArguments(bundle1);
54                 FragmentTransaction transaction1=fragmentManager.beginTransaction();
55                 transaction1.replace(R.id.content,fragmentA);
56                 transaction1.commit();
57                 break;
58             case R.id.item2:
59                 FragmentB fragmentB=new FragmentB();
60                 Bundle bundle2=new Bundle();
61                 bundle2.putString("Buser",thename);
62                 fragmentB.setArguments(bundle2);
63                 FragmentTransaction transaction2=fragmentManager.beginTransaction();
64                 transaction2.replace(R.id.content,fragmentB);
65                 transaction2.commit();
66                 break;
67             case R.id.item3:
68                 FragmentC fragmentC=new FragmentC();
69                 Bundle bundle3=new Bundle();
70                 bundle3.putString("Cuser",thename);
71                 fragmentC.setArguments(bundle3);
72                 FragmentTransaction transaction3=fragmentManager.beginTransaction();
73                 transaction3.replace(R.id.content,fragmentC);
74                 transaction3.commit();
75                 break;
76                 default:
77                     break;
78         }
79     }
80 }

 

接下来是界面设计

 

 

 

 

 分三个fragment的xml界面以及包含底部导航栏的xml界面。

activity_search.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".Search"
    android:orientation="vertical">
    //这个RelativeLayout用于嵌入Fragment,注意权值
    <RelativeLayout
        android:id="@+id/content"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1"
        ></RelativeLayout>
    //设置底部导航栏,注意权值设置
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:orientation="horizontal"
        >
        <TextView
            android:id="@+id/item1"
            android:layout_width="match_parent"
            android:layout_height="40dp"
            android:layout_weight="1"
            android:text="收入"
            android:textSize="30dp"
            android:gravity="center"
            ></TextView>
        <TextView
            android:id="@+id/item2"
            android:layout_width="match_parent"
            android:layout_height="40dp"
            android:layout_weight="1"
            android:text="支出"
            android:textSize="30dp"
            android:gravity="center"
            ></TextView>
        <TextView
            android:id="@+id/item3"
            android:layout_width="match_parent"
            android:layout_height="40dp"
            android:layout_weight="1"
            android:text="总览"
            android:textSize="30dp"
            android:gravity="center"
            ></TextView>
    </LinearLayout>

</LinearLayout>

 

 

预设置RelativeLayout,这个部分是用来显示Fragment画面的,设置权值weight为1。底部导航栏用LinearLayout设置即可

activity_fragment.xml(收入)

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     xmlns:app="http://schemas.android.com/apk/res-auto"
 4     xmlns:tools="http://schemas.android.com/tools"
 5     android:layout_width="match_parent"
 6     android:layout_height="match_parent"
 7     android:gravity="center"
 8     >
 9     <TextView
10         android:layout_width="match_parent"
11         android:layout_height="match_parent"
12         android:text="收入"
13         android:textSize="30dp"
14         android:gravity="center_horizontal"
15         android:textColor="#000000"
16         ></TextView>
17 
18     <ListView
19         android:id="@+id/lv_mes1"
20         android:layout_width="match_parent"
21         android:layout_height="wrap_content"
22         android:layout_marginTop="40dp"
23         android:layout_marginBottom="60dp"
24         ></ListView>
25 
26 </RelativeLayout>

 

 

activity_fragment_b.xml(支出)

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     xmlns:app="http://schemas.android.com/apk/res-auto"
 4     xmlns:tools="http://schemas.android.com/tools"
 5     android:layout_width="match_parent"
 6     android:layout_height="match_parent"
 7     tools:context=".FragmentB">
 8 
 9     <TextView
10         android:layout_width="match_parent"
11         android:layout_height="match_parent"
12         android:text="支出"
13         android:textSize="30dp"
14         android:gravity="center_horizontal"
15         android:textColor="#000000"
16         ></TextView>
17 
18     <ListView
19         android:id="@+id/lv_mes2"
20         android:layout_width="match_parent"
21         android:layout_height="wrap_content"
22         android:layout_marginTop="40dp"
23         android:layout_marginBottom="60dp"
24         ></ListView>
25 
26 </RelativeLayout>

 

 

activity_fragment_c.xml(总览)

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     xmlns:app="http://schemas.android.com/apk/res-auto"
 4     xmlns:tools="http://schemas.android.com/tools"
 5     android:layout_width="match_parent"
 6     android:layout_height="match_parent"
 7     tools:context=".FragmentC">
 8 
 9     <TextView
10         android:layout_width="match_parent"
11         android:layout_height="match_parent"
12         android:text="总览"
13         android:textSize="30dp"
14         android:gravity="center_horizontal"
15         android:textColor="#000000"
16         ></TextView>
17 
18     <ListView
19         android:id="@+id/lv_mes3"
20         android:layout_width="match_parent"
21         android:layout_height="wrap_content"
22         android:layout_marginTop="40dp"
23         android:layout_marginBottom="60dp"
24         ></ListView>
25 
26 </RelativeLayout>

 

 使用Fragment配合底部导航栏难度并不高,这种写法应用很广泛,至少这么写我可以避免页面跳转。显示数据也是使用ListView来实现。使用Fragment需要注意的是传值问题,一开始我想用intent进行传值,发现不可行,经过学习得知fragment传值需要节主bundle实现,当然还有其他方法,但这里没有写。

之后是ListView的应用展示,使用ListView需要适配器,而且应用时ListView的显示格式需要另设置xml文件。上面展示的fragment相关的xml代码已经调用了ListView控件,即:

1 <ListView
2         android:id="@+id/lv_mes1"
3         android:layout_width="match_parent"
4         android:layout_height="wrap_content"
5         android:layout_marginTop="40dp"
6         android:layout_marginBottom="60dp"
7         ></ListView>

ListView设置的格式文件如下:

list_item.xml

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     android:layout_width="match_parent"
 4     android:layout_height="match_parent"
 5     android:orientation="horizontal">
 6     <TextView
 7         android:id="@+id/tv_name"
 8         android:layout_width="0dp"
 9         android:layout_height="wrap_content"
10         android:gravity="center_horizontal"
11         android:layout_weight="1"
12         android:hint="商品"
13         android:textSize="12dp"
14         android:textColor="#6666FF"
15         ></TextView>
16 
17     <TextView
18         android:id="@+id/tv_money"
19         android:layout_width="0dp"
20         android:layout_height="wrap_content"
21         android:gravity="center_horizontal"
22         android:layout_weight="1"
23         android:hint="价格"
24         android:textSize="12dp"
25         android:textColor="#6666FF"
26         ></TextView>
27 
28     <TextView
29         android:id="@+id/tv_date"
30         android:layout_width="0dp"
31         android:layout_height="wrap_content"
32         android:gravity="center_horizontal"
33         android:layout_weight="1"
34         android:hint="日期"
35         android:textSize="12dp"
36         android:textColor="#6666FF"
37         ></TextView>
38 
39     <TextView
40         android:id="@+id/tv_inout"
41         android:layout_width="0dp"
42         android:layout_height="wrap_content"
43         android:gravity="center_horizontal"
44         android:layout_weight="1"
45         android:hint="收/支"
46         android:textSize="12dp"
47         android:textColor="#6666FF"
48         ></TextView>
49 
50 </LinearLayout>

要实现ListView,还需要将它们“拼接”起来。

首先是Info类:

 1 package com.example.vacation;
 2 
 3 public class MesInfo {
 4     private int Id;
 5     private String Username;
 6     private String Name;
 7     private String Money;
 8     private String Date;
 9     private String Inout;
10 
11     public int getId(){
12         return Id;
13     }
14     public void setId(int id){
15         Id=id;
16     }
17     public String getUsername(){
18         return Username;
19     }
20     public void setUsername(String username){
21         Username=username;
22     }
23     public String getName(){
24         return Name;
25     }
26     public void setName(String name){
27         Name=name;
28     }
29     public String getMoney(){
30         return Money;
31     }
32     public void setMoney(String money){
33         Money=money;
34     }
35     public String getDate(){
36         return Date;
37     }
38     public void setDate(String date){
39         Date=date;
40     }
41     public String getInout(){
42         return Inout;
43     }
44     public void setInout(String inout){
45         Inout=inout;
46     }
47 }

 

之后是adapter(拼接开始)

 1 package com.example.vacation;
 2 
 3 import android.content.Context;
 4 import android.view.LayoutInflater;
 5 import android.view.View;
 6 import android.view.ViewGroup;
 7 import android.widget.BaseAdapter;
 8 import android.widget.TextView;
 9 
10 import androidx.recyclerview.widget.RecyclerView;
11 
12 import java.util.ArrayList;
13 //适配器操作
14 public class MesAdapter extends BaseAdapter {
15     private Context context;
16     //创建列表
17     private ArrayList<MesInfo> listData;
18 
19     public MesAdapter(Context context,ArrayList<MesInfo> listData){
20         this.context=context;
21         this.listData=listData;
22     }
23     //必要步骤
24     @Override
25     public int getCount() {
26         return listData.size();
27     }
28 
29     @Override
30     public Object getItem(int position) {
31         return listData.get(position);
32     }
33 
34     @Override
35     public long getItemId(int position) {
36         return position;
37     }
38 
39     @Override
40     public View getView(int position, View convertView, ViewGroup parent) {
41         ViewHolder viewHolder=null;
42         if(convertView==null){
43             LayoutInflater inflater=LayoutInflater.from(context);
44             //这里将ListView的格式xml文件名称写入,名字千万别写错,否则调用后显示的格式会发生错误
45             convertView=inflater.inflate(R.layout.list_item,null);
46             viewHolder=new ViewHolder();
47             viewHolder.tv_name=(TextView)convertView.findViewById(R.id.tv_name);
48             viewHolder.tv_money=(TextView)convertView.findViewById(R.id.tv_money);
49             viewHolder.tv_date=(TextView)convertView.findViewById(R.id.tv_date);
50             viewHolder.tv_inout=(TextView)convertView.findViewById(R.id.tv_inout);
51             convertView.setTag(viewHolder);
52         }
53         viewHolder=(ViewHolder)convertView.getTag();
54         MesInfo model=listData.get(position);
55         viewHolder.tv_name.setText(model.getName());
56         viewHolder.tv_money.setText(model.getMoney());
57         viewHolder.tv_date.setText(model.getDate());
58         viewHolder.tv_inout.setText(model.getInout());
59         return convertView;
60     }
61 
62 }
63 class ViewHolder{
64     public TextView tv_name;
65     public TextView tv_money;
66     public TextView tv_date;
67     public TextView tv_inout;
68 }

ListView的适配器操作有很多函数,但在Android Studio上编写继承时,编辑器会自动帮你列出,只要填充内容即可,需要注意的便是注释的地方,那里填写你所设计的ListView样式的xml文件,这样在调用时会按照你设置的xml格式来显示。

最后就是删除按钮,只是一个简单的监听事件:

case R.id.delete:
                //删除按钮
                sqLiteDatabase.delete("message","musername=?",new String[]{searchname});
                Toast.makeText(Work.this,"记入信息删除成功",Toast.LENGTH_SHORT).show();
                break
;

看看效果:

 

 

 

 

删除成功。

posted @ 2020-02-23 18:27  千幽行  阅读(353)  评论(0编辑  收藏  举报