RecyclerView的数据刷新

今天在写Demo的时候,看到官方对notifyDataSetChanged()这样描述的一段话:
重点内容
If you are writing an adapter it will always be more efficient to use the more specific change events if you can. Rely on notifyDataSetChanged() as a last resort.

官方说道如果你在使用一个适配器的时候,你能够使用一个更加具体的改变事件来获取更高的效率,把notifyDataSetChanged() 作为最后的使用手段.

于是乎,就有了这么几个方法:
重点内容
notifyItemChanged(int)
notifyItemInserted(int)
notifyItemRemoved(int)
notifyItemRangeChanged(int, int)
notifyItemRangeInserted(int, int)
notifyItemRangeRemoved(int, int)

这六个方法,是RecyclerView特有的,对于ListVIew是没有这几个方法的,下面我们对这六个方法一一探索,先看看官方描述:
notifyItemChanged(int)

Notify any registered observers that the item at position has changed.Equivalent to calling notifyItemChanged(position, null);
This is an item change event, not a structural change event. It indicates that any reflection of the data at position is out of date and should be updated.
The item at position retains the same identity.

(翻译的很烂的中文:)提醒任何一个注册了的观察者,这个item在position位置上已经发生了改变,这等同于notifyItemChanged(position, null),这是一个item改变的事件,不是结构改变的事件,它暗示着任何从这个位置上反射出去的数据已经过期了,应该要被更新,处于这些位置上的item的身份特征不会改变(猜测是实列对象).

notifyItemRemoved(int)

Notify any registered observers that the item previously located at position has been removed from the data set. The items previously located at and after position may now be found at oldPosition - 1.
This is a structural change event. Representations of other existing items in the data set are still considered up to date and will not be rebound, though their positions may be altered.

(翻译的很烂的中文:)提醒任何一个注册的观察者,这个之前处于position位置上的item已经从数据集合中被移除了,之前位于position之后的item现在可能会在oldPosition-1的位置上找到.
这是一个结构改变事件,这代表着其他一些存在的item在这个数据集合中仍然会被认为是最新的,这不会触发重新绑定,虽然他们的position可能发生了改变.

notifyItemInserted(int)

Notify any registered observers that the item reflected at position has been newly inserted. The item previously at position is now at position position + 1.
This is a structural change event. Representations of other existing items in the data set are still considered up to date and will not be rebound, though their positions may be altered.

这个意思和上面的差不多,就不翻译了.

其他三个是范围内的改变,意思也差不多,通过看源码发现,上面三个方法其实就是调用了下面三个与之对应的方法,只是把range写为了1.


看完了官方描述,本人带着官方的描述去打了demo,实践了几波之后,总结如下:

1:官方说道的结构改变事件和item改变事件是什么意思?

我们都知道,无论是listView还是RecyclerView,都是一个高度定制的ViewGroup,我们加进去的一个个item,其实就是一个个的子view,排列在其中,对于官方所说的结构改变事件,是指item增加或者减少的情况,因为这涉及到对其他子view的重新布局和绘制,所以官方认为这是一个结构改变事件.
而官方描述的item改变事件,是指仅仅是因为这个item和数据集合中的数据不对应了,item所显示的数据已经过期了,应该更新了,而item的位置并不会发生改变,也就不会触发重新布局和绘制.

2:notifyItemChanged(int) 和notifyItemInserted(int) ,notifyItemRemoved(int)的区别是什么?他们会触发onBindViewHolder吗?

如前面官方描述的那样,实践后发现notifyItemInserted(int) ,notifyItemRemoved(int),并不会触发onBindViewHolder,因为他只是一个结构改变事件,仅仅把position位置上的item删除或者插入了一条,其他已经存在的item对于数据集合来说,仍然是被认为是最新的,虽然他们的position发生了改变,所以他们不会触onBindViewHolder,

那么对于notifyItemChanged(int)来说,鄙人也验证了官方的说法,这个方法认为处于任何从position映射出去的数据相对于数据集合来说已经过期了,需要重新更新,但
是每个位置上的item的实例对象不会改变,所以会导致相应的位置会触发onBindViewHolder重新绑定数据.

通过对上面官方描述的理解,也就可以解释为什么官方推荐你在写一个适配器的时候,使用某些更加具体的改变事件会有更高的效率,最后再贴一段对notifyDataSetChanged()的官方描述:

Notify any registered observers that the data set has changed.
There are two different classes of data change events, item changes and structural changes. Item changes are when a single item has its data updated but no positional changes have occurred. Structural changes are when items are inserted, removed or moved within the data set.
This event does not specify what about the data set has changed, forcing any observers to assume that all existing items and structure may no longer be valid. LayoutManagers will be forced to fully rebind and relayout all visible views.
RecyclerView will attempt to synthesize visible structural change events for adapters that report that they have stable IDs when this method is used. This can help for the purposes of animation and visual object persistence but individual item views will still need to be rebound and relaid out.

不翻译了,哈哈哈哈……..

猜你喜欢

转载自blog.csdn.net/djh2717/article/details/81075639