Элемент recyclerview меняет стиль кнопки после прокрутки

У меня есть recyclerview с простыми элементами - элемент имеет изображение, заголовок и кнопку. Когда пользователь нажимает кнопку, ему необходимо изменить свой макет -> указать, что кнопка нажата (аналогично функциональности флажка).

Проблема в том, что когда я нажимаю кнопку, например, второй элемент, он ведет себя странно при прокрутке - переключаются несколько элементов или исходный не переключается. Вы можете проверить это на изображении здесь:

ПРЕДПРОСМОТР GIF

@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));
    }
}

person John Huggins    schedule 09.11.2016    source источник
comment
вам нужно получить позицию элемента, а затем применить свой стиль, то, что вы сейчас делаете, это просто стиль одного элемента, а стилизованный элемент перерабатывается и используется другими элементами   -  person Mohammed Elrashied    schedule 09.11.2016


Ответы (3)


Вам нужно указать позицию для метода onBindView, так как он вызывается несколько раз. Если вы используете неизменяемые типы AutoValue, вы можете попытаться создать массив логических значений, в котором вы будете хранить переключаемые состояния (true/false). Затем в onBindViewMethod проверьте значение текущей позиции и стиль кнопки.

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;
        }

    });
}
person mayosk    schedule 09.11.2016

Раньше у меня тоже было странное поведение. Для меня это было решено простым вызовом

toggle.invalidate();

после вашего блока if/else. Это вызывает перерисовку. Попробуйте, я тоже был удивлен, что это исправило это для меня.

person Grisgram    schedule 09.11.2016

Проверьте мой код

 @Override
public void onBindViewHolder(GifGridAdapter.ViewHolder holder, final int position) {
    final DataModel model = arrayList.get(position);
    if (model.isToggle()) {
//Code for changing the button background color and text color
    } else {
//Code for changing the button background color and text color
    }


    holder.ivGif.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
    model.setToggle(!model.isToggle());
    notifyDataSetChanged();

        }
    });
}
person Mavya Soni    schedule 09.11.2016
comment
Я использую библиотеку AutoValue, поэтому моя модель неизменна, поэтому я использую button.setActivated(true); - person John Huggins; 09.11.2016