在保持ListView滚动位置的情况下更新SimpleCursorAdapter

9
我的问题:每当我通过自定义的SimpleCursorAdapter更新ListView的内容时,它会重置其滚动位置到顶部。我希望ListView在更新时保持其滚动位置。
一开始我是每次创建一个新的适配器实例,并使用ListView.setAdapter(),但根据this discussion所说,我应该更新适配器而不是重置它。但我找不到一种适用于SimpleCursorAdapter的正确方法来做到这一点。
以下是我尝试过的一些方法,省略了方法参数:
- 使用新的游标调用SimpleCursorAdapter.changeCursorAndColumns()可以成功更新适配器,但仍会重置滚动位置。
- SimpleCursorAdapter.changeCursor()的作用方式相同。
- api 11才有SimpleCursorAdapter.swapCursor(),而我正在开发api 8。
- SimpleCursorAdapter.notifyDataSetChanged()无法更新ListView。(可能我漏掉了其他步骤。)
- ListView.invalidate()无法更新ListView。
- SimpleCursorAdapter.requery()会使ListView变空,并且已被弃用。
- 我熟悉ListView.setSelection()解决方案,但当更新ListView时,我不希望它移动。这会将其捕捉到列表中的一个位置。
这似乎是一个常见且简单的问题。有人处理过吗?

请看我的回复。SimpleCursorAdapter.changeCursor() 是可以正常工作的 - 我只是有另外一行代码搞砸了事情。 - pvans
2个回答

5
我曾经遇到过类似的问题:当光标内容改变时,我的CursorAdapter会重置滚动位置。
我并没有意识到每次数据改变时我都设置了一个新的列表适配器。我以为光标会通知适配器内容已经改变,但在我的情况下,是ContentProvider触发LoaderManager.LoaderCallbacks.onLoadFinished()回调,在这个回调中,我现在使用CursorAdapter.changeCursor()而不是创建一个新的适配器,这样一切都正常工作。
希望这能帮助解决你的问题。

原来SimpleCursorAdapter.changeCursor()是正常工作的。在我这种情况下导致listview滚动位置重置的罪魁祸首是一对代码行,在更改光标之前称为ListView.SetDivider()ListView.SetDividerHeight。真的很烦人。我还有一个ListView.setCacheColorHint()行,它不会导致滚动位置重置。 - pvans

0
在Async Task的post execute中执行相同操作,我使用了以下代码,对我有效。
 Cursor cursor = mDataHelper.getWritableDatabase().query(
                        DataContract.Incares.TABLE_NAME,  // Table to Query
                        null, // all columns
                        null, // Columns for the "where" clause
                        null, // Values for the "where" clause
                        null, // columns to group by
                        null, // columns to filter by row groups
                        DataContract.Incares.UUID +" DESC" // sort order
                );
CursorAdapter.changeCursor(cursor);
CursorAdapter.notifyDataSetChanged();

由于CursorAdapter是全局变量


除非您有不关闭旧游标的理由,否则请使用CursorAdapter.changeCursor(cursor)而不是“交换”。 - Renate

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接