Article
RecyclerView Trick: Selectively bind ViewHolders with Payloads
December 20, 2017
What if you want to update a single item in a
RecyclerView
but don’t want to rebind the entire view? There’s actually a variation ofnotifyItemChanged
that allows us to do just that:
Before:
Consider this example click handler for a RecyclerView
item:
After the call to notifyItemChanged
, the adapter gets notified and onBindViewHolder
gets called. Unfortunately, rebinding the entire view can lead to some visual quirks*:
What if we only want to update the parts of the view that actually changed? When we notify our adapter, we can pass along a “payload” object:
Then we add logic to our adapter to handle these special “payloads”:
After:
This strategy has a few advantages:
- We keep all of our view binding logic contained inside of our
Adapter
classes. - We have flexible options about how to bind: only want to bind certain parts of the View? Sure. Want animations to show the change, but only on certain updates? Yup. Want to chain together multiple calls to
notifyItemChanged
to reflect multiple updates? You betcha,onBindViewHolder
will give you an entireList<Object>
that has all of your payloads merged together. - We can always fallback to a default update; any time the adapter doesn’t know how to handle a certain payload, the view gets fully rebound.
Happy recycling!
*The background flash is actually intended behavior and occurs because of DefaultItemAnimator
's implementation of the “change” animation. Calling setSupportChangeAnimations(false)
would also “fix” the background flash. This solution is a bit heavy handed, however. Disabling change animations on the ItemAnimator
will stop all animations when often times we only want to disable some animations.
-
Andrew Haisting
Software Engineer