Android: RecyclerView.Adapter doesn't work as expected
When you setHasStableIds(true)
you must implement getItemId(int position)
with return position
.
You current piece of code setHasStableIds(true)
only told your adapter that items will not change for given position and adapter no need to call onBindViewHolder for this position again
Massimo Baldrighi
I entered the software development world 6 years ago, and since then I have always emerged as a highly motivated developer, with excellent analytical and logical skills, and very flexible and adaptable, especially when requirements made me come out of my comfort zone and new technical skills were needed from me. I have been alternating for quite some time Android and ReactNative development.
Updated on June 17, 2022Comments
-
Massimo Baldrighi almost 2 years
My question id directly related to @Richard's one about the method onBindViewHolder() within the RecyclerView.Adapter is not called as he (and I) expected it to do.
I noticed that this method is called correctly until the end of my dataset (9 CardViews, scrolling down), but when I try to get back (scrolling up) it's not called anymore. The real problem is that in there I make my changes in the dataset and call notifyDataSetChanged(), but with this strange (to me) behavior my modifications don't take place when they are supposed to do.
The picture I attach wants to try to clarify:
- I reach the bottom of the Rec.View (cardView - Supine: everything's fine);
- dealing with the cards already showed completely or partially there is no problem (Supine, Gerund and Participle);
- but when I reach the first cardView completely obscured, onBindViewHolder() is not called anymore and I can see from the debug that the dataset linked to the adapter is the "Supine" one, and here it is: the Supine cardView is showed.
I thought that it was the exact same issue Richard faced in his question, and I tried his exact same solution: I forced setHasStableIds() to true in my Adapter's constructor,
public CardAdapter(List<Object> items){ this.items = items; adapterList = new ArrayList<String>(); formAdapt = new ConjFormAdapter(adapterList); itemMap = new HashMap<Object, Long>(); setHasStableIds(true); }
where itemMap is the Map I implement in my activity to set the unique ids of my dataset,
and overrode getItemId() this way:
public long getItemId(int position) { Object item = items.get(position); return itemMap.get(item); }
But as you can see from the picture I still get this result: any idea, please?
Edit
The implementation of itemMap in my activity:
for(int i=0, j=0; i<conj_items.size(); i++, j++) conjAdapter.getItemMap().put(conj_items.get(i), (long) j);
where conj_items is the ArrayList I pass to the Adapter.
-
User over 5 years
return position
is not advisable unless you know that your lists items (more exactly their "identities") will not change during updates. If it's possible that new items are added, removed, or moved, this will not work. You should use a unique identifier of the item instead.