通知 RecyclerView 适配器有关不可见项更改的正确方法是什么?
What's the proper way of notifying a RecyclerView adapter about changes in non-visible items?
我会尽量具体一点。我有一个游标支持的 RecyclerView 适配器。我正在使用 LoaderManager 回调在 DB 值更改时获取更新,这为我提供了一个新游标。然后,我将新光标与适配器当前持有的光标进行比较,以确定发生了什么变化,在适配器中用新光标替换旧光标,然后调用适当的 notifyItem(Range)Inserted/Changed/Removed()
函数。这很好用,但有些地方我想使用它可以有一些相当大的游标,所以我希望通过使用布局管理器确定哪些项目可见然后只检查这些项目来优化它游标进行更改,而不是检查每一行。
现在我的问题是,假设我有一个包含 1000 行的游标,而我的 RecyclerView 显示的是第 0-10 行。我可以遍历游标,检查索引 0-10 处的项目是否有 changes/additions/deletions 并调用适当的 notify() 函数,就像我目前正在做的那样,但是不可见的项目呢?我是否必须通知适配器这些行中可能有更改,或者我是否可以安全地忽略它们,它只会在这些行被绑定时使用更新的数据?
为清楚起见进行编辑,我的代码流程是这样的:
我的适配器有一个游标,getItemCount
只是 returns cursor.count()
并且 ViewHolder
绑定代码是 cursor.moveToPosition(position)
后面跟着一些东西喜欢 ViewHolder.setFoo(cursor.getString(BAR))
当数据库发生变化时,LoaderManager
回调调用 onLoadFinished
并更新游标,然后调用 adapter.changeCursor(newCursor)
changeCursor
基本上遍历旧游标和新游标以检查发生了什么变化。这工作正常,但如果光标非常大,可能需要一些时间来循环整个事情,所以我希望能够跳过除了可见项目之外的所有内容。如果我这样做,更改工作正常,因为 onBindViewHolder
将使用更新的游标,但如果添加或删除(不可见的)行并且我不调用 notifyItemInserted/Removed
,则适配器不会知道它并且没有正确处理它,这让我相信我不能做这个优化,我必须循环整个事情来找到 added/removed 行
你的直觉是正确的。
您无需担心不可见的项目。当 LayoutManager
最终将它们放在屏幕上时,您将在适配器中收到对 bindViewHolder
的调用。在这里,您将在视图中反映适配器(有您的光标)的当前状态。
我会尽量具体一点。我有一个游标支持的 RecyclerView 适配器。我正在使用 LoaderManager 回调在 DB 值更改时获取更新,这为我提供了一个新游标。然后,我将新光标与适配器当前持有的光标进行比较,以确定发生了什么变化,在适配器中用新光标替换旧光标,然后调用适当的 notifyItem(Range)Inserted/Changed/Removed()
函数。这很好用,但有些地方我想使用它可以有一些相当大的游标,所以我希望通过使用布局管理器确定哪些项目可见然后只检查这些项目来优化它游标进行更改,而不是检查每一行。
现在我的问题是,假设我有一个包含 1000 行的游标,而我的 RecyclerView 显示的是第 0-10 行。我可以遍历游标,检查索引 0-10 处的项目是否有 changes/additions/deletions 并调用适当的 notify() 函数,就像我目前正在做的那样,但是不可见的项目呢?我是否必须通知适配器这些行中可能有更改,或者我是否可以安全地忽略它们,它只会在这些行被绑定时使用更新的数据?
为清楚起见进行编辑,我的代码流程是这样的:
我的适配器有一个游标,getItemCount
只是 returns cursor.count()
并且 ViewHolder
绑定代码是 cursor.moveToPosition(position)
后面跟着一些东西喜欢 ViewHolder.setFoo(cursor.getString(BAR))
当数据库发生变化时,LoaderManager
回调调用 onLoadFinished
并更新游标,然后调用 adapter.changeCursor(newCursor)
changeCursor
基本上遍历旧游标和新游标以检查发生了什么变化。这工作正常,但如果光标非常大,可能需要一些时间来循环整个事情,所以我希望能够跳过除了可见项目之外的所有内容。如果我这样做,更改工作正常,因为 onBindViewHolder
将使用更新的游标,但如果添加或删除(不可见的)行并且我不调用 notifyItemInserted/Removed
,则适配器不会知道它并且没有正确处理它,这让我相信我不能做这个优化,我必须循环整个事情来找到 added/removed 行
你的直觉是正确的。
您无需担心不可见的项目。当 LayoutManager
最终将它们放在屏幕上时,您将在适配器中收到对 bindViewHolder
的调用。在这里,您将在视图中反映适配器(有您的光标)的当前状态。