I have a basic RecyclerView
setup on a chat-like app and I have hit an issue with the item animations.
The project is making use of Room
with Paging 3
and DiffUtils
for the RecyclerView
adapter, so this is all automated, but the core of the problem can be simplified to this:
- When I send a new message, that message is added to the
RecyclerView
- here the adapter is triggering
notifyItemInserted
ornotifyItemRangeInserted
which causes the entire message list to shift up softly and the new message fades in after
- here the adapter is triggering
- I scroll the list to the bottom so the new added item becomes visible
- When I receive a
read
status from the server I update the status of that message- here the adapter is triggering
notifyItemChanged
ornotifyItemRangeChanged
which has no default animations on its own, it just updates the item with the new information
- here the adapter is triggering
All of this is working well on its own, but the problem is when I receive a status update from the server faster than the insert animation has a chance to finish. When that happens the notifyItemChanged
or notifyItemRangeChanged
kicks in and skips the animation initiated by notifyItemInserted
or notifyItemRangeInserted
. The list till shifts upwards, but the fade in no longer happens, instead the item is instantly made visible all the while the list is still shifting up, overlaying the item previously occupying that last position causing an ugly visual experience.
I can kinda "cheat" by delaying the step in 2.
to engage after the animation is supposedly over, but then it introduces another visual issue if the user sends multiple messages quickly or receives them in the same fashion.
In this example there are 2 recyclerviews set up with the same adapter slightly changed to make it easier to compare the issue in the same action.
The left recyclerview is not doing any update when an item is inserted, but it is the behavior I expect to display even if I update the item during the item insertion animation. On the right recyclerview is the actual problem, as you can see new items are showing in full over the old ones before they have a chance to move out of the way. The first example recording has scroll to bottom with no delay after the item is inserted, the second example has a delay that matches the insertion animation duration.
Reminder: this is just a manual example, the real application in my case is being done automatically via the integration I mentioned above, I am not the one in control of when the notifyItem*
calls are made at any point.
How can I make sure the insert animation does not get interrupted even if I am updating the item data in the middle of the animation?
https://stackoverflow.com/questions/65820901/recyclerview-item-inserted-with-item-updated-is-skipping-inserted-animation January 21, 2021 at 11:46AM
没有评论:
发表评论