哪个更贵,notifyDatasetChanged()或者循环一个大的游标? [英] Which is more expensive, notifyDatasetChanged() or looping over a large cursor?

查看:250
本文介绍了哪个更贵,notifyDatasetChanged()或者循环一个大的游标?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

基本上,我有一个RecyclerView与适配器填充光标的数据。我有两个选项来获取项目动画:

Basically, I have a RecyclerView with an adapter populating the data from a cursor. I have two options to get item animations:


  1. 使用 setHasStableIds(true)并覆盖 getItemId 以返回数据库行的ID,然后在适配器中使用 swapCursor 函数使用新的光标交换其当前光标,然后调用 notifyDatasetChanged

  1. Use setHasStableIds(true) and override getItemId to return the ID of the database row, and then use a swapCursor function in the adapter that swaps its current cursor with the new one and then calls notifyDatasetChanged

与选项1类似,只需交换游标并调用 notifyDatasetChanged ,遍历旧的和新的游标,比较行以确定哪些行已添加/删除/更改,然后调用 notifyItemAdded notifyItemChanged 等告诉适配器明确更新了什么

Similar to option 1, but instead of simply swapping the cursor and calling notifyDatasetChanged, iterate over the old and new cursor, comparing the rows to determine which rows have been added/deleted/changed and keeping track of them, then calling notifyItemAdded, notifyItemChanged, etc. to tell the adapter specifically what's been updated

对于选项1, notifyDatasetChanged 会重新绑定所有可见项)这是低效的,但是使用选项2,我将不得不循环整个光标以确定哪些项目已添加/删除,如果光标相当大,这也可能需要一些时间。

With option 1, notifyDatasetChanged will re-bind all the visible items (and some other stuff) which is inefficient, but with option 2 I would have to loop over the full cursor to figure out which items have been added/deleted, and if the cursor is fairly large, this could also take some time. Does anyone have any ideas about which would be the better solution and why?

编辑:

要做的事情更有趣的是,我还有第三个选项:

To make things even more interesting, I also have a third option:


  1. 与选项2类似,在游标中,只迭代当前绑定的项目(通过检查 RecyclerView 的子项),因为其他人将拾取新的游标值,当他们绑定。唯一的问题是它不适用于添加/删除,所以如果 oldCursor.count()!= newCursor.count()。如果计数相同,我可以做 setHasStableIds(false),然后即使在一个位置的行不同于以前, onBindViewHolder 会照顾它。

  1. Similar to option 2, but instead of iterating over every item in the cursor, only iterate over the currently bound items (figured out by checking the RecyclerView's children) since the others will pick up the new cursor values when they're bound. The only problem with this is that it doesn't work for additions/deletions, so the way around it would be to do a full iteration if oldCursor.count() != newCursor.count(). If the counts are the same, I can do setHasStableIds(false) and then even if the row at a position is different than it was previously, onBindViewHolder will take care of it.

这样做的缺点是ID不稳定表示 RecyclerView 在某些地方需要做一些额外的工作

Downsides of this would be that the ID's aren't stable, which means the RecyclerView will have to do some extra work in some places

推荐答案

选项2容易出错。我会选择1,保持简单。

Option 2 is prone to errors. I would go with option 1, keep it simple.

这篇关于哪个更贵,notifyDatasetChanged()或者循环一个大的游标?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆