我认为您的问题是 arg2 是列表中的位置,不等于显示的行的 id。
也就是说,如果您选择第一个项目,那么它的位置,因此 arg2 将是 0。
假设您在 id 列中使用 INTEGER PRIMARY KEY 或 INTEGER PRIMARY KEY AUTOINCREMENT,那么第一个 ID 可能是 1,接下来是 2 等等(但是您永远不应该依赖它,例如,如果行被删除,那么该 id 很可能不会被重新使用并且序列被破坏)。
如果列表视图使用 CursorAdapter,
arg3 将具有 id BUT ONLY (我建议这样做,因为那时您不需要中间数组,刷新列表只需重建光标并使用swapCursor 或notifyOnDatasetChanged,我更喜欢前者,因为它更具描述性)。
PS 如果您确实使用 CursorAdapter,则 id 列必须被称为 _id(有一些方法可以通过 SELECT 查询中的 AS 重命名/创建列,但 imo 最好使用 _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)));
比较 ArrayAdapter 和 CursorAdapter 的工作示例
这与使用 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;
Activity 的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);
}
示例展示:-
在Left列表(ArrayAdapter)中点击Lamb(第一项)后:-
点击右列表(CursorAdapter)中的Beef(现在是第3项)后:-