Massimo Baldrighi
Massimo Baldrighi

Reputation: 365

Android: RecyclerView.Adapter doesn't work as expected

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:

Scrolling up from the bottom of the RecyclerView - Sorry for the quality

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.

Upvotes: 4

Views: 12778

Answers (2)

wildcat12
wildcat12

Reputation: 1020

I had the same exception, but it was actually caused by a different issue. After trying setHasStableIds(true) and setLayoutTransition(null), each with no luck, I realized that I was adding the view to the parent in onCreateViewHolder (which I shouldn't have been doing because the adapter takes care of that for you). I removed that, and the issue was resolved.

@Override
public TopTrayIconAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

    DMImageView icon = new DMImageView(mContext);
    LinearLayout.LayoutParams faceParams = new LinearLayout.LayoutParams(ICON_WIDTH, ICON_WIDTH);
    faceParams.gravity = Gravity.CENTER;
    faceParams.leftMargin = 15;
    faceParams.rightMargin = 15;

    parent.addView(icon, faceParams);  <- THIS WAS THE ISSUE

Upvotes: 0

Vlad  Palamarchuk
Vlad Palamarchuk

Reputation: 89

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

Upvotes: 7

Related Questions