今天继续在昨天的基础上完成了家庭记账单的在数据库中的添加和查看功能
在之前的基础上舍弃了Fragment,重新在百度上找到了学习资料,并且自我完成了实践
首先在之前的基础上创建CostListAdapter.java,并根据提示创建四个方法:
package com.example.familybook; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.TextView; import java.util.List; public class CostListAdapter extends BaseAdapter { private List<CostBean> mList; private Context mContext; private LayoutInflater mLayoutInflater; public CostListAdapter(Context context,List<CostBean>list){ mContext=context; mList=list; mLayoutInflater=LayoutInflater.from(context); } @Override public int getCount() { return mList.size(); } @Override public Object getItem(int position) { return mList.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder viewHolder; if(convertView==null){ viewHolder=new ViewHolder(); convertView=mLayoutInflater.inflate(R.layout.list_item,null); viewHolder.mTvCostTitle=(TextView)convertView.findViewById(R.id.tv_title); viewHolder.mTvCostMoney=(TextView)convertView.findViewById(R.id.tv_cost); viewHolder.mTvCostDate=(TextView)convertView.findViewById(R.id.tv_date); convertView.setTag(viewHolder); } else{ viewHolder=(ViewHolder)convertView.getTag(); } //取出Bean对象 CostBean bean=mList.get(position); viewHolder.mTvCostTitle.setText(bean.costTitle); viewHolder.mTvCostDate.setText(bean.costDate); viewHolder.mTvCostMoney.setText(bean.costMoney); return convertView; } private static class ViewHolder{ public TextView mTvCostTitle; public TextView mTvCostDate; public TextView mTvCostMoney; } }
新建DatabaseHelper继承自SQLiteHelper,创建新的数据库和相关的信息表,这和之前的博客一样
package com.example.familybook; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import androidx.annotation.Nullable; public class DatabaseHelper extends SQLiteOpenHelper { public static final String COST_MONEY = "cost_money"; public static final String COST_DATE = "cost_date"; public static final String COST_TITLE = "cost_title"; public static final String ACCOUNT_COST = "account_cost" ; public DatabaseHelper(@Nullable Context context) { super(context, "account_daily", null, 1); } @Override public void onCreate(SQLiteDatabase db) { db.execSQL("create table if not exists account_cost("+ "id integer primary key,"+ "cost_title varchar,"+ "cost_date varchar,"+ "cost_money varchar)"); } //插入 public void insertCost(CostBean costBean){ SQLiteDatabase database=getWritableDatabase();//获取数据库对象 ContentValues cv=new ContentValues(); cv.put(COST_TITLE,costBean.costTitle); cv.put(COST_DATE,costBean.costDate); cv.put(COST_MONEY,costBean.costMoney); database.insert(ACCOUNT_COST,null,cv); } //查询 public Cursor getAllCostData(){ SQLiteDatabase database=getWritableDatabase(); return database.query(ACCOUNT_COST ,null,null,null,null,null,COST_DATE+" ASC"); } //删除 public void deleteAllData(){ SQLiteDatabase database=getWritableDatabase(); database.delete("account_cost",null,null); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } }
最后在主函数中添加点击事件,以及功能,并使用fab
package com.example.familybook; import android.content.DialogInterface; import android.database.Cursor; import android.os.Bundle; import com.google.android.material.floatingactionbutton.FloatingActionButton; import com.google.android.material.snackbar.Snackbar; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.Toolbar; import android.renderscript.Script; import android.view.LayoutInflater; import android.view.View; import android.view.Menu; import android.view.MenuItem; import android.widget.DatePicker; import android.widget.EditText; import android.widget.ListView; import java.util.ArrayList; import java.util.List; public class MainActivity extends AppCompatActivity { private List<CostBean> mCostBeanList; private DatabaseHelper mDatabaseHelper; private CostListAdapter adapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Toolbar toolbar = findViewById(R.id.toolbar); setSupportActionBar(toolbar); mDatabaseHelper=new DatabaseHelper(this); mCostBeanList=new ArrayList<>(); //给ListView设置写好的适配器 ListView costList=(ListView)findViewById(R.id.lv_main); initCostData(); adapter=new CostListAdapter(this,mCostBeanList); costList.setAdapter(adapter); FloatingActionButton fab = (FloatingActionButton)findViewById(R.id.fab); fab.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { AlertDialog.Builder builder= new AlertDialog.Builder(MainActivity.this); LayoutInflater inflater=LayoutInflater.from(MainActivity.this); View viewDialog=inflater.inflate(R.layout.new_cost_data,null); final EditText title=(EditText)viewDialog.findViewById(R.id.et_cost_title); final EditText money=(EditText)viewDialog.findViewById(R.id.et_cost_money); final DatePicker date=(DatePicker)viewDialog.findViewById(R.id.dp_cost_date); builder.setView(viewDialog); builder.setTitle("添加新的账单"); builder.setPositiveButton("确定", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { CostBean costBean=new CostBean(); costBean.costTitle=title.getText().toString(); costBean.costMoney=money.getText().toString(); costBean.costDate=date.getYear()+"-"+(date.getMonth()+1)+"-"+ date.getDayOfMonth(); mDatabaseHelper.insertCost(costBean);//调用插入函数 mCostBeanList.add(costBean); adapter.notifyDataSetChanged();//时时刷新界面 } }); builder.setNegativeButton("返回",null); builder.create().show();//没有他触发事件不会显示出来 } }); } private void initCostData() { // mDatabaseHelper.deleteAllData(); // for (int i=0;i<6;i++) { // CostBean costBean = new CostBean(); // costBean.costTitle = i+"mock"; // costBean.costDate = "11-11"; // costBean.costMoney = "20"; //mCostBeanList.add(costBean); // mDatabaseHelper.insertCost(costBean); // } Cursor cursor=mDatabaseHelper.getAllCostData(); if(cursor!=null){ while(cursor.moveToNext()){ CostBean costBean=new CostBean(); costBean.costTitle=cursor.getString(cursor.getColumnIndex("cost_title")); costBean.costDate=cursor.getString(cursor.getColumnIndex("cost_date")); costBean.costMoney=cursor.getString(cursor.getColumnIndex("cost_money")); mCostBeanList.add(costBean); } cursor.close(); } } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.menu_main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); //noinspection SimplifiableIfStatement if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } }
在网上学习的资料虽然分块化明显,有制作家庭记账本的简单思路和步骤,但是在我真正实践起来却有很多的麻烦,也遇到了很多问题,这些问题也弄了很长时间,在其中真的意识到了编写代码边测试的重要性
问题一:当运行成功后,弹出添加新账单按钮的时候,点击确定添加,界面不做出任何反应,并且不显示添加的内容,这个问题解决了很长时间
原因:在主函数中没有用builder调用show函数,通过查阅资料发现,如果在主函数中完成添加后,不写语句,会导致触发事件没有反应。
问题二:当触发事件有反应但是没有添加成功,自己所添加的信息无法显示
原因:和上一个问题出现在相同的位置,当从new_cost_data.xml界面获取到所填信息之后,没有书写添加语句,即
问题三:和问题二有相同之处,但是不同的是,他完成了添加,但是只有在重启页面或者重新运行代码的时候才会显示更新添加的新帐单的内容
查找原因过程和思路:这就说明了数据库的添加和查看没有了问题。百度发现了一个之前从没有见过的问题,为时时更新数据,
原因:主函数中,没有书写时时更新数据的代码
在新建界面的时候会自动生成这样的代码,选中右键——Refactor——Extract——Field新建类为adapter,有的版本为mAdapter,将其装换成一下代码
然后将数据读取添加后在书写时时刷新界面的代码
运行结果: