更新 SimpleCursorAdapter,同时保持 ListView 中的滚动位置

Posted

技术标签:

【中文标题】更新 SimpleCursorAdapter,同时保持 ListView 中的滚动位置【英文标题】:Update SimpleCursorAdapter while maintaining scroll position in ListView 【发布时间】:2012-03-04 13:54:44 【问题描述】:

我的问题:每当我通过其(自定义)SimpleCursorAdapter 更新其内容时,我的 ListView 会将其滚动位置重置为顶部。我希望 ListView 在更新时保持其滚动位置。

我开始时每次都创建一个新的适配器实例并使用ListView.setAdapter(),但根据this discussion,我应该更新适配器而不是重置它。我找不到能正常工作的 SimpleCursorAdapter 的方法。

以下是我尝试过的一些方法,省略了方法参数: - SimpleCursorAdapter.changeCursorAndColumns() 使用新光标成功更新适配器,但仍重置滚动位置。 - SimpleCursorAdapter.changeCursor() 的行为方式相同。 - SimpleCursorAdapter.swapCursor() 直到 api 11 才可用,我正在为 api 8 开发。 - SimpleCursorAdapter.notifyDataSetChanged() 不更新 ListView。 (也许我还缺少另一个步骤。) - ListView.invalidate() 不会更新 ListView。 - SimpleCursorAdapter.requery() 使 ListView 变为空白,已弃用。 - 我熟悉 ListView.setSelection() 解决方案,但我不希望我的 ListView 在更新时移动。这会将其捕捉到列表中的某个位置。

这似乎应该是一个常见且简单的问题。有人处理过吗?

【问题讨论】:

在答案下方查看我的评论。 SimpleCursorAdapter.changeCursor() 确实可以正常工作 - 我只是有另一行代码搞砸了。 【参考方案1】:

在异步任务的后期执行中使用以下代码对我有用

 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),而不是“交换”【参考方案2】:

我遇到过类似的问题:每当光标内容发生变化时,我的 CursorAdapter 都会重置滚动位置。

我没有意识到每次数据更改时我确实设置了一个新的列表适配器。我认为光标本身会通知适配器其内容的更改,但在我的情况下,它是 ContentProvider 在我的 ListFragment 中触发 LoaderManager.LoaderCallbacks.onLoadFinished()。在该回调中,我现在使用 CursorAdapter.changeCursor() 而不是创建新适配器,一切正常。

我希望这有助于解决您的问题。

【讨论】:

事实证明 SimpleCursorAdapter.changeCursor() 工作正常。在我的例子中,导致列表视图滚动位置重置的罪魁祸首是在更改光标之前调用的一对代码行:ListView.SetDivider()ListView.SetDividerHeight。真烦人。我还有一个ListView.setCacheColorHint() 行,它不会导致滚动位置重置。

以上是关于更新 SimpleCursorAdapter,同时保持 ListView 中的滚动位置的主要内容,如果未能解决你的问题,请参考以下文章

数据库更改时,Android SimpleCursorAdapter 不会更新

SimpleCursorAdapter无法在MainActivity中使用

使用 SimpleCursorAdapter 从 Cursor 更改值

SimpleCursorAdapter使用代码

带有 SimpleCursorAdapter 的 AutoCompleteTextView 用于加载联系人

SimpleCursorAdapter 在 bindView 上重复单击操作