I'm dynamically adding Views to my items in a RecyclerView
. These added Views should only be related to the item which they're added to, but I'm having a problem when I scroll. It seems the View
is recycled and a new item is loaded, but those previously added views are still there, only now on the wrong item.
I'm assuming that it's just because the ViewHolder
is being reused, so the added items show up again with a new item, when loaded.
How would one go about solving this?
First of all, can you share some more code please?
Second, why would you want to dynamically add new views on fly? Why don't you use different VIEWTYPE or just have those view already on your layout and just make them visible/invisible or visible/gone? (I believe it will be more efficient this way).
Let me remind you something about RecyclerView, yes when user is scrolling viewHolder are being reused (few of them can be created, even more than it needs to fill the screen). So if it happened that you added some views on "item A" and user scroll to "item Z", that viewHolder can be reused for that "item Z", hence the show up of the previously added views.
How can you solve that?
Well always check on every items if you need to add new views, if yes add them if not already added, else always remove those views (if present) to return to default viewHolder state (or whatever you call it).
Hope this will help you.
In your adapter class of your
recyclerView
, in theonBindViewHolder
method, create another adapter and do the same methods for your new adapter.The hierarchy will be,
This way you can achieve what you want without wrong values to be viewed on wrong items.
Save Information by tags for items with new child each time the Add newView operation occur. (In shared preference for example) Tag: create with item position onBindViewHolder.
when load Adapter get this value and put default as null. I am not sure about its efficiency but i will work.
if you know some possible viewTypes for example always going to be ImageView & TextView so with some if statement it will be ok.
Good Luck
You need to track what views have been added based on the backing data. I would probably add any necessary extra views in
onBindViewHolder()
, and remove any that might be present inonViewRecycled()
. Then when you want to make one appear dynamically, change whatever variable you have tracking whether it should be visible, and callnotifyItemChanged()
.This was an old question of mine. A bounty was placed on it, hence the surge of popularity and the multiple new and irrelevant answers.
As stated in both my comment to this answer and @CQM's comment below my original question, the answer is to override the
onViewRecycled()
method and perform any needed operations there. This method is called when a view is recycled, and any cleanup operations can be done here.Documentation on this method can be found here.
In my case, it was a matter of deleting the invisible
TextView
's attached to the view. The text itself had been deleted, but the view remained. If many invisibleTextView
's accumulate on the view and aren't properly recycled when scrolling, the scroll will begin to lag.You can use this!
setItemViewCacheSize(int size)
Check here RecyclerViewDocumentation.