Адаптер Android onItemНажмите на RecyclerView влияет на несколько элементов View

1

У меня есть RecyclerView и соответствующий адаптер, в котором я создал интерфейс OnItemClickListener.

Я пытаюсь передать само представление (onclicked) реализации в Activity, и оно получает несколько элементов. На самом деле, изменение, которое я хочу внести в элемент представления, затрагивает более одного элемента в списке представления переработчика. Я хочу изменить фон элемента в списке, но фон другого элемента тоже меняется.

Вот адаптер:

public class TranslationAdapter extends RecyclerView.Adapter<TranslationAdapter.TranslationHolder> {
private List<String> translations = new ArrayList<>();

private OnItemClickListener listener;

@NonNull
@Override
public TranslationHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
    View itemView = LayoutInflater.from(viewGroup.getContext())
            .inflate(R.layout.translation_item, viewGroup, false);

    return new TranslationHolder(itemView);
}

@Override
public void onBindViewHolder(@NonNull TranslationHolder translationHolder, int i) {
...
}

public void setTranslations(List<String> _translations){
    this.translations = _translations;
    notifyDataSetChanged();
}

class TranslationHolder extends RecyclerView.ViewHolder{
    private TextView tvTranslation;

    public TranslationHolder(@NonNull final View itemView) {
        super(itemView);
        tvTranslation = itemView.findViewById(R.id.text_view_translation);

        itemView.setOnClickListener(v -> {
            int position = getAdapterPosition();
            if (listener != null && position != RecyclerView.NO_POSITION){
                listener.onItemClick(v, translations.get(position));
            }
        });
    }
}

public interface OnItemClickListener{
    void onItemClick(View view, String string);
}

public void setOnItemClickListener(OnItemClickListener listener){
    this.listener = listener;
}
}

и вот реализация в Деятельности:

public class TranslationActivity extends AppCompatActivity {
     RecyclerView recyclerView;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_translation);

    recyclerView = findViewById(R.id.recycler_view);
    recyclerView.setLayoutManager(new LinearLayoutManager(this));
    recyclerView.setHasFixedSize(true);

    recyclerView.setAdapter(adapter);        
}
 @Override
protected void onStart() {
    super.onStart();
     adapter.setOnItemClickListener((v, translation) -> {
        if (arrResultOfTranslation.contains(translation)){
            arrResultOfTranslation.remove(translation);
            v.setBackgroundColor(Color.BLUE);
        }
        else {
            v.setBackgroundColor(Color.YELLOW);
            arrResultOfTranslation.add(translation);
        }
    });
    }
}

В результате, хотя я получаю только один строковый элемент (перевод), цвет фона нескольких элементов меняется. Когда я отлаживаю, я вижу только один экземпляр View (переменная v).

Теги:
android-recyclerview

2 ответа

1
Лучший ответ

Попробуй это

RecyclerViewAct.java

public class RecyclerViewAct extends Activity {
    private static final String TAG = "RecyclerViewAct";
    private RecyclerView recyclerView;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.recycler_main);
        recyclerView = findViewById(R.id.recycler_view);

        recyclerView.setLayoutManager(new LinearLayoutManager(this));

        MyAdapter adapter = new MyAdapter();

        List<String> data = new ArrayList<>();
        for (int i = 0; i < 30; i++) {
            data.add("item" + i);
        }

        adapter.setData(data);
        recyclerView.setAdapter(adapter);

        adapter.setOnClickListener(new MyAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(List<String> results) {
                Log.e(TAG, "onItemClick: " + results.size());
            }
        });

    }
}

MyAdapter.java

    class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyHolder> {

    private List<String> data = new ArrayList<>();
    private List<String> results = new ArrayList<>();

    public void setData(List<String> data) {
        this.data = data;
        notifyDataSetChanged();
    }

    @NonNull
    @Override
    public MyHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_recycler, parent, false);
        return new MyHolder(itemView);
    }

    @Override
    public void onBindViewHolder(@NonNull final MyHolder holder, final int position) {

        holder.textView.setText(data.get(position));


        if (results.contains(data.get(position))) {
            holder.textView.setBackgroundColor(Color.BLUE);
        } else {
            holder.textView.setBackgroundColor(Color.WHITE);
        }

        holder.textView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String str = data.get(position);
                if (results.contains(data.get(position))) {
                    results.remove(str);
                    holder.textView.setBackgroundColor(Color.WHITE);
                } else {
                    holder.textView.setBackgroundColor(Color.BLUE);
                    results.add(str);
                }

                // selected list
                if (onClickListener != null) {
                    onClickListener.onItemClick(results);
                }

            }
        });
    }

    @Override
    public int getItemCount() {
        return data.size();
    }

    OnItemClickListener onClickListener;

    public interface OnItemClickListener {
        void onItemClick(List<String> results);

    }

    public void setOnClickListener(OnItemClickListener onClickListener) {
        this.onClickListener = onClickListener;
    }

    class MyHolder extends RecyclerView.ViewHolder {
        TextView textView;

        public MyHolder(View itemView) {
            super(itemView);

            textView = itemView.findViewById(R.id.tv_item);

        }

    }
}
  • 0
    Этот ответ помог мне решить проблему, добавив несколько дополнительных настроек. простой, но мощный! Интересно, как другие люди справляются с этой «ошибкой». должна быть какая-то лучшая практика для этого, но не может найти какую-либо.
0

Проблема здесь в том, что переработчик повторно использует его,

Мое предложение состоит в том, чтобы сделать Pojo с вашей строкой и флагом, может быть логическим, и когда вы нажимаете на этот элемент, установите логический флаг как истинный

в вашем onBindViewholder проверьте, установлен ли флаг в true, установите нужные вам пользовательские свойства

Ещё вопросы

Сообщество Overcoder
Наверх
Меню