Android开发:保存多列数据仅显单列ListView及加载崩溃求助
这个问题其实分两步就能搞定:先处理多列数据的存储,再实现ListView的单列展示~
第一步:保存多列数据到数据库
你的DBAdapter里需要写一个对应的插入方法,比如叫insertBill,接收所有要存储的字段(比如账单名称、金额、日期这类),然后用ContentValues把每个字段的键值对封装好,再调用SQLiteDatabase的insert方法完成存储。举个简单示例:
public long insertBill(String name, double amount, String date) { SQLiteDatabase db = this.getWritableDatabase(); ContentValues values = new ContentValues(); values.put(COLUMN_BILL_NAME, name); // COLUMN_BILL_NAME是你定义的列名常量 values.put(COLUMN_AMOUNT, amount); values.put(COLUMN_DATE, date); // 执行插入,返回插入的行ID long id = db.insert(DB_TABLE_NAME, null, values); db.close(); return id; }
第二步:ListView仅显示单列
从数据库查询数据时,你可以获取包含所有列的Cursor,但只提取你想展示的那一列数据,把它们放到ArrayList<String>里,再用ArrayAdapter绑定到ListView就可以了。比如你想显示账单名称:
// 在DBAdapter里新增一个获取单列数据的方法 public ArrayList<String> getAllBillNames() { ArrayList<String> billNames = new ArrayList<>(); SQLiteDatabase db = this.getReadableDatabase(); // 只查询账单名称这一列 Cursor cursor = db.query(DB_TABLE_NAME, new String[]{COLUMN_BILL_NAME}, null, null, null, null, null); if (cursor.moveToFirst()) { do { // 提取每一行的账单名称 String name = cursor.getString(cursor.getColumnIndex(COLUMN_BILL_NAME)); billNames.add(name); } while (cursor.moveToNext()); } cursor.close(); // 用完Cursor一定要关闭! db.close(); return billNames; }
然后在MainActivity里绑定数据:
// 加载ListView数据的方法 private void loadBillList() { ArrayList<String> billNames = dbAdapter.getAllBillNames(); // 用系统自带的简单布局,把数据绑定到ListView ListAdapter adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, billNames); mrecycleview.setAdapter(adapter); }
这样ListView就只会显示账单名称这一列啦~
从你贴的代码来看,你把mlistview();注释掉了,这应该是加载ListView数据的核心方法吧?给你梳理几个最常见的崩溃原因,你可以逐一排查:
1. Cursor处理不当
这是最容易踩的坑!如果查询后没关闭Cursor,或者没判断Cursor是否为空就直接取数据,很容易崩溃。比如直接写cursor.getString(0)但Cursor是空的,就会抛出CursorIndexOutOfBoundsException。一定要注意:
- 查询后先判断
cursor != null - 取数据前要调用
cursor.moveToFirst(),并且判断返回值是否为true - 用完Cursor必须调用
cursor.close()
2. 列名写错了
如果DBAdapter里定义的列名和查询时用的不一致,比如定义的是COLUMN_BILL_TITLE,但查询时写的是COLUMN_BILL_NAME,Cursor获取数据时就会抛出异常,一定要仔细核对列名常量!
3. ListView初始化问题
检查布局文件里的ListView id是不是mRecycleView,有没有和代码里的findViewById对应上,要是id写错了,mrecycleview就是null,调用setAdapter时就会空指针崩溃。
给你一个参考的加载数据方法
把你注释掉的mlistview()改成这样试试:
private void mlistview() { ArrayList<String> billData = new ArrayList<>(); Cursor cursor = dbAdapter.getAllBills(); // 假设这个方法返回所有账单的Cursor if (cursor != null) { if (cursor.moveToFirst()) { do { // 提取你要显示的列,这里以账单名称为例 String billName = cursor.getString(cursor.getColumnIndex(DBAdapter.COLUMN_BILL_NAME)); billData.add(billName); } while (cursor.moveToNext()); } cursor.close(); // 必须关闭Cursor! } // 初始化Adapter并绑定到ListView ListAdapter adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, billData); mrecycleview.setAdapter(adapter); }
然后在onCreate里取消注释mlistview();,另外,从Editbills页面返回后,记得在onResume方法里再调用一次mlistview()刷新数据哦~
最后,强烈建议你查看Logcat的错误日志!崩溃时会弹出具体的异常信息(比如NullPointerException、CursorIndexOutOfBoundsException),这能帮你瞬间定位问题,比瞎猜高效多啦!
内容的提问来源于stack exchange,提问作者dhruv sachdeva

