RecyclerView Trick: Selectively bind ViewHolders with Payloads
What if you want to update a single item in a
RecyclerViewbut don’t want to rebind the entire view? There’s actually a variation of
notifyItemChangedthat allows us to do just that:
Consider this example click handler for a
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”:
This strategy has a few advantages:
- We keep all of our view binding logic contained inside of our
- 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
notifyItemChangedto reflect multiple updates? You betcha,
onBindViewHolderwill give you an entire
List<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.
*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.