【问题标题】:Deleting items in a CursorAdapter删除 CursorAdapter 中的项目
【发布时间】:2014-03-05 08:05:09
【问题描述】:

我有一个CursorAdapter 的实现,我通过ListFragmentLoader 一起使用。除了下面的问题外,这工作正常。它包含以下代码。每行包含一个复选框,用户可以在其中选择项目。操作栏上有一个删除按钮,允许用户删除选定的项目。这是通过我对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
        }

}

这里是ContentProvider中对应的函数:

@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;
}

当我选择多个项目并删除时,它第一次可以正常工作并完成它应该做的事情。但是,现在如果我选择更多的一个或多个项目,然后再次单击删除,它会在第 XX 行失败。

我在 LogCat 中遇到的错误是 java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteQuery: SELECT id as _id, name, value FROM stufftable WHERE (value=?)。它失败的那一行是:cursor.moveToPosition(checkedItemKey)

我确实查看了this,并了解不知何故我将光标置于关闭或不一致的状态。但是,我想不出任何可以解决我的问题的方法。我做错了什么?

注意:我在我的ContentProvider.delete() 中调用getContext().getContentResolver().notifyChange(uri, null),我认为它与Loader 一起会通知光标。我还尝试将this.notifyDataSetChanged() 放在最后,但没有任何运气。

【问题讨论】:

  • 发布 logcat 并完成 ContentProvider

标签: android android-cursoradapter illegalstateexception android-cursor


【解决方案1】:

每次输入时在 deleteStuff() 中创建一个新的光标,而不是使用来自 newView 的光标,用于搜索要删除的条目。 (这应该有效)

您也可以尝试使用 bindView 中的光标,但我不确定这是否可行。

【讨论】:

  • 我认为这不是一个好主意。使用CursorAdapterLoader/LoaderManager 的意义在于我不必自己管理光标:)
  • 它是用来加载的,你也可以在 deleteStuff() 的末尾尝试 cursor.requery(),但是这个方法似乎已经被弃用了。让我知道您是否尝试过以及是否有效。同时我会想一个更好的办法。
  • 您也可以尝试使用 bindView 中的光标(视图视图、上下文上下文、光标光标)。我认为 bindView 使用刷新的光标。
  • 感谢您的意见。是的,我找到了一个更好的方法,并会尽快将其作为正确答案发布!
【解决方案2】:

更新:我终于以更简单的方式做到了这一点。我正在用位于 bindView() 内的 CheckBox.setOnCheckedChangeListener() 内的位置填充checkedItems。我将其更改为包含要删除的项目的 id 而不是获取位置,然后使用带有位置的光标:)。所以在 delete() 中,我已经准备好要删除的 Id,我不必在这里弄乱光标。这如我所愿。我希望我早点想到这一点,那么我就不必在这里发布问题了。我希望这对某人有帮助!

【讨论】:

    猜你喜欢
    • 2016-11-27
    • 1970-01-01
    • 2021-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-02
    • 2016-06-01
    相关资源
    最近更新 更多