Android 删除游标适配器中的项
我有一个Android 删除游标适配器中的项,android,android-cursoradapter,illegalstateexception,android-cursor,Android,Android Cursoradapter,Illegalstateexception,Android Cursor,我有一个CursorAdapter的实现,通过ListFragment与Loader一起使用。除了下面的问题外,这工作正常。它包含以下代码。每行包含一个复选框,用户可以在其中选择项目。actionbar上有一个删除按钮,允许用户删除所选项目。这是通过我实现的ContentProvider实现的 @Override public View newView(Context context, Cursor cursor, ViewGroup parent) { //some logic
CursorAdapter
的实现,通过ListFragment
与Loader
一起使用。除了下面的问题外,这工作正常。它包含以下代码。每行包含一个复选框,用户可以在其中选择项目。actionbar上有一个删除按钮,允许用户删除所选项目。这是通过我实现的ContentProvider
实现的
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
//some logic
this.cursor = cursor; //class variable assignment
}
void deleteStuff() {
if (cursor == null) {
return;
}
if (checkedItems == null || checkedItems.size()==0) { //A Sparse boolean array which saves the positions of items the user selected
return;
}
final SparseIntArray checkedKeys = new SparseIntArray(); //positions of selected items
final SparseLongArray checkedIds = new SparseLongArray(); //ids of the items at the resp keys
for (int i = 0; i < checkedItems.size(); i++) {
final int checkedItemKey = checkedItems.keyAt(i);
checkedKeys.append(i, checkedItemKey);
cursor.moveToPosition(checkedItemKey); //the line at which it fails!!!!!!!!
checkedItemIds.append(checkedItemKey, Long.parseLong(c.getString(0)));
}
for (int i = 0; i < checkedItems.size(); i++) {
myContentProvider.delete(uri, selection, args); //not putting the code for these 3 variables as not required
}
}
当我选择多个项目并删除时,它第一次工作正常,并执行它应该执行的操作。但是,现在如果我再选择一些项目,然后再次单击delete,它将在第XX行失败
我在LogCat中遇到的错误是java.lang.IllegalStateException:尝试重新打开已关闭的对象:SQLiteQuery:从stufftable中选择id作为\u id、名称、值,其中(值=?)
。失败的行是:cursor.moveToPosition(checkedItemKey)
我确实看到了,并且理解了,不知何故,我让光标处于关闭或不一致的状态。然而,我想不出任何办法来解决我的问题。我做错了什么
注意:我正在调用我的
ContentProvider.delete()
中的getContext().getContentResolver().notifyChange(uri,null)
,我认为它与加载程序一起将通知光标。我还尝试将this.notifyDataSetChanged()
放在末尾,但没有任何运气。每次输入时都在deleteStuff()中创建一个新光标,而不是使用newView中的光标,该光标搜索要删除的条目。(这应该行得通)
您也可以尝试使用bindView中的光标,但我不确定这是否有效。更新:我最终以一种更简单的方式完成了此操作。我正在用bindView()中的CheckBox.setOnCheckedChangeListener()中的位置填充checkedItems。我将其更改为包含要删除的项目的id,而不是获取位置,然后使用光标和位置:)。因此,在delete()中,我已经准备好了要删除的ID,并且我不必在这里弄乱光标。这是我想要的。我要是早点想到这一点就好了,这样我就不用把问题贴在这里了。我希望这对别人有帮助 发布日志和完整的内容提供者我认为这不是一个好主意。将CursorAdapter
与Loader/LoaderManager
一起使用的要点是,我不必自己管理游标:)它是用于加载的,您也可以在deleteStuff()的末尾尝试cursor.requery(),但此方法似乎已被弃用。让我知道你是否试过,是否有效。同时,我会想一个更好的方法。你也可以尝试使用bindView中的游标(视图视图、上下文、游标)。我认为bindView使用了一个刷新的光标。谢谢您的输入。是的,我找到了一个更好的方法,并将很快将其作为正确答案发布!
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
int uriType = sURIMatcher.match(uri);
SQLiteDatabase sqlDB = sqlitehelper.getWritableDatabase();
int rowsDeleted = sqlDB.delete(TJItemTable.TABLE_NAME, selection, selectionArgs);
getContext().getContentResolver().notifyChange(uri, null);
return rowsDeleted;
}