Как сделать изменение дизайна item в recyclerView при клике на него?
Есть адаптер и я не понимаю как мне в нем сделать чтобы при клике на элемент он становился с определенным фоном, а при клике на другой элемент соответственно тот новый элемент приобретал новый фон , а старый итем применял дефолтный фон. Подскажите , как можно реализовать такую логику, это логика обычного выбора размера в карточке товара.
public class RecyclerViewOfferSizeAdapter extends RecyclerView.Adapter<RecyclerViewOfferSizeAdapter.SizeViewHolder>{
public interface OnStateClickListener {
void onStateClick(OffersItems offersItems, int position);
}
private final List<OffersItems> listSizes;
private final OnStateClickListener onClickListener;
private final LayoutInflater inflater;
public RecyclerViewOfferSizeAdapter(Context context, List<OffersItems> listSizes, OnStateClickListener onClickListener) {
this.onClickListener = onClickListener;
this.listSizes = listSizes;
this.inflater = LayoutInflater.from(context);
}
@NonNull
@Override
public SizeViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.activity_catalog_element_inf_tp,
parent, false);
return new SizeViewHolder(view);
}
public void setListSizes(List<OffersItems> offersItems){
listSizes.addAll(offersItems);
notifyDataSetChanged();
}
public void clearItems(){
listSizes.clear();
notifyDataSetChanged();
}
@Override
public void onBindViewHolder(@NonNull SizeViewHolder holder, int position) {
OffersItems offersItems = listSizes.get(position);
holder.size.setText(offersItems.getSizeOffer());
holder.itemView.setOnClickListener(v -> {
onClickListener.onStateClick(offersItems, position);
});
}
@Override
public int getItemCount() {
return listSizes.size();
}
public static class SizeViewHolder extends RecyclerView.ViewHolder{
private final TextView size;
private final RelativeLayout relative;
public SizeViewHolder(@NonNull View itemView) {
super(itemView);
size = itemView.findViewById(R.id.textSize);
relative = itemView.findViewById(R.id.relativeLayoutSize);
}
}
}
Получившийся код не пропускает в switch
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position, @NonNull List<Object> payloads) {
if(!payloads.isEmpty()) {
switch (payloads.get(0)) {
case 1:
if (lastPosition >= 0){
notifyItemChanged(lastPosition, 2);
}
lastPosition = position;
holder.itemView.setBackgroundColor(Color.parseColor("#8DFFFFFF"));
break;
case 2:
holder.itemView.setBackgroundColor(Color.parseColor("#FFFFFF"));
break;
default:
break;
}
}else {
super.onBindViewHolder(holder, position, payloads);
}
User user = users.get(position);
holder.mTextUserName.setText(user.getName());
holder.mTextUserAge.setText(user.getAge());
holder.itemView.setOnClickListener(view -> {
onClickListener.onStateClick(user, position);
});
}
Ответы (1 шт):
Как вариант использовать notifyItemChanged(int position, Object payload). Для этого в адаптере где у вас есть клик делаете вызов :
notifyItemChanged(position, 1);
и дальше в адаптере переопределяете метод:
@Override
public void onBindViewHolder(ViewHolder holder, int position, List<Object> payloads) {
if(!payloads.isEmpty()) {
}else {
super.onBindViewHolder(holder,position, payloads);
}
}
внутри условия вы проверяете какой идентификатор у вашего изменения:
switch (payloads.get(0)) {
case 1:
holder.itemView.setBackgroundColor(Color.parseColor("#8DFFFFFF"));
break;
case 2:
holder.itemView.setBackgroundColor(Color.parseColor("#8DFFFFFF"));
break;
default:
break;
}
но вопрос в том как отловить выбор другого элемента отличного от уже выбранного. Для этого я бы предложил сохранять последнюю выбранную позицию и при клике ее обновлять:
public class RecyclerViewOfferSizeAdapter extends RecyclerView.Adapter<RecyclerViewOfferSizeAdapter.SizeViewHolder>{
private Integer lastPosition = -1;
....
}
при клике вы будете менять фон:
notifyItemChanged(position, 1);
внутри условия с case 1 проверяете:
case 1:
if (lastPosition >= 0){
notifyItemChanged(lastPosition, 2);
}
lastPosition = position;
holder.itemView.setBackgroundColor(Color.parseColor("#8DFFFFFF"));
break;
ну а в case 2 возвращаете нужный вам цвет. По логике должно работать нормально.
UPDATE
Вот метод полностью:
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position, @NonNull List<Object> payloads) {
if (!payloads.isEmpty()) {
switch ((Integer) payloads.get(0)) {
case 1:
for (int i = 0; i < getItemCount(); i++) {
if(i == position){
holder.itemView.setBackgroundColor(Color.parseColor("#343434"));
}else{
int finalI = i;
Completable.complete()
.observeOn(AndroidSchedulers.mainThread())
.subscribe(() -> {
notifyItemChanged(finalI,2);
});
}
}
break;
case 2:
holder.itemView.setBackgroundColor(Color.parseColor("#FFFFFF"));
break;
default:
break;
}
} else {
super.onBindViewHolder(holder, position, payloads);
}
}