RecyclerView NotifyItemInserted


RecyclerView NotifyItemInserted



I have a RecyclerView.Adapter with hasStableIds(true); and a LinearLayoutManager with reverseLayout(true);


RecyclerView.Adapter


hasStableIds(true);


LinearLayoutManager


reverseLayout(true);



I insert a new item to the object list in the adapter then call NotifyItemInserted(0). The list is reversed and loads from bottom to top with the new item always at the bottom.


NotifyItemInserted(0)


new item



The problem is when calling NotifyItemInserted all of the ViewHolders are "Refreshed" / "Reloaded" / "Recreated" - The viewholders are a bit complex and do not want them all to be recreated each time.


NotifyItemInserted



When I debug the solution, OnBindViewHolder starts from position 0 (Which is correct) then goes up to position 10 or 11 depending on how many items there are on screen, recreating them all.


OnBindViewHolder



I have tried many different settings on the adapter, layoutmanager and the recyclerview itself which none of them work.


adapter


layoutmanager


recyclerview



I see there is a payload which can be passed in NotifyItemChanged but not in NotifyItemInserted. Maybe with the payload I can check whether the item is already on screen and don't recreate it again, I don't know what to do.


NotifyItemChanged


NotifyItemInserted



I am using Xamarin.Android but that should not be a problem here.





Instead of using notifyItemInserted(0), try using notifyItemInserted(position)
– Mehul Kanzariya
Jul 3 at 9:31





You insert the new item in position 0 and then you reverse the list and you put it last? Is this correct?
– mTak
Jul 3 at 9:52





@mTak Well, the new items are always in position 0. The list of objects is reversed in itself and the recyclerview displays items from bottom to top.
– Pierre
Jul 3 at 9:55






@MehulKanzariya I have tried notifyItemInserted(list.Length) without any luck
– Pierre
Jul 3 at 10:00





@Pierre Before called notifyItemInserted, are you added that row to the arraylist?
– Mehul Kanzariya
Jul 3 at 10:02




1 Answer
1



Removing hasStableIds(true) should solve your problem.


hasStableIds(true)



Reason:



When you set hasStableIds to true, the Adapter assumes that every item has a unique id, and it uses the values returned from the getItemId(int position) method to animate data changes for you.


hasStableIds


true


Adapter


getItemId(int position)



That's an easy way to animate changes without any effort (As long as the getItemId(int position) really returns a unique id per item, otherwise you'll crash).


getItemId(int position)



But in your case you want to animate changes by yourself and control which items will be re-rendered and which will not.






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

PHP contact form sending but not receiving emails

Do graphics cards have individual ID by which single devices can be distinguished?

iOS Top Alignment constraint based on screen (superview) height