Amir Panahandeh
Amir Panahandeh

Reputation: 9039

Items of RecyclerView are not showing correctly

In my onBindViewHolder of my RecyclerView.Adapter<SearchAdapter.ViewHolder> when user clicks on cardview a button becomes visible. But when I'm scrolling recyclerview some other items buttons are shown as visible too. Why is this happening?

this is my code:

@Override
public void onBindViewHolder(final ViewHolder viewHolder, final int position) {
    viewHolder.card.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (viewHolder.content_layout.getVisibility() == View.VISIBLE) {
                viewHolder.content_layout.setVisibility(View.GONE);
                viewHolder.address.setMaxLines(2);
                viewHolder.attribute.setMaxLines(2);
            } else {
                viewHolder.content_layout.setVisibility(View.VISIBLE);
                viewHolder.address.setMaxLines(8);
                viewHolder.attribute.setMaxLines(8);
            }
        }
    });
    ...
}

Upvotes: 12

Views: 1747

Answers (4)

Wackaloon
Wackaloon

Reputation: 2365

Good idea is to make a class object with all data you need for one item in recycler view, also add there one boolean isItemWasClicked and inside onBindViewHolder() check this boolean and make buttons visible or not. For example:

public class OneItemOfList{
    int priceToDisplay;
    String name;
    String date;
    boolean wasClicked;
}

public class YourAdapter extends RecyclerView.Adapter<OneItemOfList.ViewHolder> {
ArrayList<OneItemOfList> items;
...
@Override
public void onBindViewHolder(ViewHolder viewHolder, final int position) {
    viewHolder.view.setText(items.get(position).name);
    if (items.get(position).wasClicked)
        viewHolder.button.setVisible(View.VISIBLE);
    else
        viewHolder.button.setVisible(View.GONE);
    viewHolder.view2.setOnClickListener(...
        OnClick(...){
            items.get(position).wasClicked = !items.get(position).wasClicked;
        });
}
...
}

Upvotes: 5

Philippe Banwarth
Philippe Banwarth

Reputation: 17755

The 'other' visible items buttons are the ones using the same viewholder that was modified in the callback. So because viewholders (and views) are recycled :

  • They should only store information that can be retrieved each time the viewholder is bound to a position.

  • Anything that may be changed in the views state should be refreshed in onBindViewHolder()

In your case you should store the 'is selected' somewhere else and reset the visibility and maxlines in onBindViewHolder() (not only in the callback)

Upvotes: 6

reVerse
reVerse

Reputation: 35264

Once you start scrolling down the list your views get recycled. This means a previously inflated ViewHolder (some that gets created in onCreateViewHolder) is reused.
So what you have to do is to remember the clicked positions (e.g. via a SparseBooleanArray) and check in onBindViewHolder whether the view should be visible (previously clicked) or not.

You can find a basic usage example of the SparseBooleanArray in this StackOverflow post

Upvotes: 11

Amin Paydar
Amin Paydar

Reputation: 97

create an array for example Boolean array, and when each position clicked, set true in same position of array. and in onBindViewHolder check if that array[position] is true set that item visible if.

Upvotes: 2

Related Questions