我试图通过点击删除带有SQLite数据的列表视图行。
当我按下listview项时没有任何反应,日志中没有错误。
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_new_meal);
userList = (ListView) findViewById(R.id.listView8);
mHelper = new DbHelper(this);
userList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
dataBase.delete(DbHelper.TABLE_NAME, DbHelper.MEAL_ID + "=" + mealId.get(arg2), null);
displayData();
}
});
private void displayData() {
dataBase = mHelper.getWritableDatabase();
Cursor mCursor = dataBase.rawQuery("SELECT * FROM "+ DbHelper.TABLE_NAME, null);
mealId.clear();
mealName.clear();
if (mCursor.moveToFirst()) {
do {
mealId.add(mCursor.getString(mCursor.getColumnIndex(DbHelper.MEAL_ID)));
mealName.add(mCursor.getString(mCursor.getColumnIndex(DbHelper.MEAL_NAME)));
} while (mCursor.moveToNext());
}
DisplayAdapter disadpt = new DisplayAdapter(NewMealActivity.this, mealId, mealName);
userList.setAdapter(disadpt);
mCursor.close();
}
}
答案 0 :(得分:0)
我认为您的问题是 arg2
是列表中的位置,不等于显示的行的ID。
即如果您选择第一个项目,那么它的位置因此 arg2 将 0 。
假设您使用INTEGER PRIMARY KEY
或INTEGER PRIMARY KEY AUTOINCREMENT
作为 id 列,那么第一个ID可能是1,接下来的2等等(但是您永远不应该依赖例如,如果删除了一行,那么很可能不会重复使用该ID并且序列被破坏了。
arg3
会有id BUT ONLY (我建议这样做,因为那时你不需要中间件数组,刷新列表只需要重建光标并使用swapCursor
或notifyOnDatasetChanged
,我更喜欢前者,因为它更具描述性。)
PS如果你确实使用了CursorAdapter,那么必须将id列称为 _id (有些方法可以在SELECT查询中通过AS重命名/创建列,但最好使用< strong> _id 作为表格中的列名。)
昨天我回答了一个非常相似的问题(更新而不是删除),我会指出你How can i update a field of my spinner with user input in EditText。
您可以进行以下更改(将ID列提取到数组中时): -
更改行
dataBase.delete(DbHelper.TABLE_NAME,
DbHelper.MEAL_ID + "=" + mealId.get(arg2), null);
到
dataBase.delete(DbHelper.TABLE_NAME,DbHelper.MEAL_ID + "=" +
mealId.get(arg2),null);
因此,您使用position作为mealId数组的索引,该数组具有正确的ID。
请注意!理想情况下mealId
应该是Long
而不是字符串,然后上面将是: -
dataBase.delete(DbHelper.TABLE_NAME,DbHelper.MEAL_ID + "=" +
Long.toString(mealId.get(arg2)),null);
与
一起 mealName.add(mCursor.getString(mCursor.getColumnIndex(DbHelper.MEAL_NAME)));
改为
mealName.add(mCursor.getLong(mCursor.getColumnIndex(DbHelper.MEAL_NAME)));
使用ArrayAdpater(DBHlper应该关闭反映你的代码(至少对于相关/使用的列)),你的代码非常相似。)
注意!使用ArrayAdapter而不是DisplayAdapter(我猜是自定义适配器)。
: -
类变量: -
DbHelper mHelper;
SQLiteDatabase dataBase;
ArrayList<String> mealName = new ArrayList<>();
ArrayList<Long> mealId = new ArrayList<>();
ArrayAdapter<String> arrayAdapter;
SimpleCursorAdapter sca;
Cursor mCursor2;
活动的onCreate
中的代码(或由onCreate
调用): -
mHelper = new DbHelper(this);
userList = (ListView) findViewById(R.id.listview);
userList2 = (ListView) findViewById(R.id.listview2);
// Add some data (note will add rows each time this is run)
mHelper.insertMeal("Fish");
mHelper.insertMeal("Beef");
mHelper.insertMeal("Lamb");
mHelper.insertMeal("Rice");
// Array method
// Looks shorter but relies upon code if displayData
userList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
dataBase.delete(DbHelper.TABLE_NAME,DbHelper.MEAL_ID + "=" +
Long.toString(mealId.get(i)),null);
displayData();
}
});
// Alternative using Cursor Adapter and thus long l (4th parameter) (the ID)
// No Need for intermediate arrays, uses the cursor directly
// (Only calls displayData to sync lists)
userList2.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
dataBase.delete(DbHelper.TABLE_NAME,DbHelper.MEAL_ID + "=" +
Long.toString(l),null);
mCursor2 = dataBase.query(DbHelper.TABLE_NAME,null,null,null,null,null,null);
sca.swapCursor(mCursor2);
// keep userList in sync with userList2
displayData();
}
});
//Initial setup of userList2
dataBase = mHelper.getWritableDatabase();
mCursor2 = dataBase.query(DbHelper.TABLE_NAME,null,null,null,null,null,null);
sca = new SimpleCursorAdapter(this,
android.R.layout.simple_list_item_1,
mCursor2,
new String[] {DbHelper.MEAL_NAME},
new int[] {android.R.id.text1},
0
);
userList2.setAdapter(sca);
//Initial setup of userList
displayData();
}
displayData 方法(除了调用同步列表之外,仅对ArrayAdpater非常需要): -
private void displayData() {
dataBase = mHelper.getWritableDatabase();
Cursor mCursor = dataBase.rawQuery("SELECT * FROM " + DbHelper.TABLE_NAME,null);
mealId.clear();
mealName.clear();
while (mCursor.moveToNext()) {
mealId.add(mCursor.getLong(mCursor.getColumnIndex(DbHelper.MEAL_ID)));
mealName.add(mCursor.getString(mCursor.getColumnIndex(DbHelper.MEAL_NAME)));
arrayAdapter = new ArrayAdapter<String>(this,
android.R.layout.simple_selectable_list_item,
mealName
);
userList.setAdapter(arrayAdapter);
}
// keep userlist 2 in sync userList
mCursor2 = mCursor; // cheat by using userList's cursor
sca.swapCursor(mCursor2);
}
示例显示: -
点击左侧列表(ArrayAdapter)中的 Lamb (第1项)后: -
点击右侧列表(CursorAdapter)中的牛肉(现在第3项)后: -