John Huggins John Huggins - 29 days ago 20
Android Question

recyclerview item changes button style after scroll

I have a recyclerview with simple items - an item has an image, title and a button. When the user clicks on the button it needs to change its layout -> indicating that button is clicked (similar to checkbox functionality).

Problem is that when I click on a button, for example the second item, it behaves weirdly when I scroll - multiple items are toggled or the original one is untoggled. You can check it out in image here:

GIF PREVIEW

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
holder.button.setOnClickListener(view -> {
toggleButtonStyle((Button)view);
});
}

public void toggleButtonStyle(Button toggle)
{
Context ctx = toggle.getContext();
if (toggle.isActivated()) {
toggle.setActivated(false);
toggle.setBackground(ContextCompat.getDrawable(ctx, R.drawable.btn_purple_corners));
toggle.setTextColor(ContextCompat.getColor(ctx, R.color.purple_light));
} else {
toggle.setActivated(true);
toggle.setBackground(ContextCompat.getDrawable(ctx, R.drawable.btn_purple));
toggle.setTextColor(ContextCompat.getColor(ctx, R.color.white));
}
}

Answer

You need to specify position for a onBindView method, because it's called multiple times. If you are using AutoValue immutable types, you can try to make an Array of booleans where you'll be storing toggled states (true/false). Then in onBindViewMethod check a value of current position and style a button.

private boolean[] toggledChoices = new boolean[yourListWithItems.size()];

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {

    if (toggledChoices[position]) {
        toggleButtonStyle(true, holder.toggleButton);
    } else {
        toggleButtonStyle(false, holder.toggleButton;
    }

    holderVote.bToggleItem.setOnClickListener(v -> {

        if (!toggledChoices[position]) {
            toggledChoices[position] = true;
        } else {
            toggledChoices[position] = false;
        }

    });
}