Работа списка RecyclerView на андроиде. Каждый 10 элемент списка имеет ссылку на тот же внутренний элемент
При создании приложения на андроид, столкнулся с тем что список RecyclerView, во время своего формирования, присваивает каждому десятому элементу, от уже имеющихся элементов этого списка, туже самую ссылку на элемент ImageView. Проще говоря, только первые 9 элементов имеют уникальную ссылку на ImageView, остальные просто копируют ее. Может кто-то сталкивался с этим, объясните почему так происходит. Не исключено что ошибка с моей стороны.
public class DataHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private final TextView topic;
private final TextView date;
private final TextView body;
private ImageView deleteMarker;
private NotesListActivity notesListActivity;
private ListItem listItem;
public DataHolder(@NonNull View itemView) {
super(itemView);
topic = itemView.findViewById(R.id.topicTv);
date = itemView.findViewById(R.id.dateTv);
body = itemView.findViewById(R.id.bodyTv);
itemView.setOnClickListener(this);
}
public void setData(ListItem listItem) {
topic.setText(listItem.getTopic());
date.setText(listItem.getDate());
body.setText(listItem.getBody());
}
@Override
public void onClick(View v) {
deleteMarker = itemView.findViewById(R.id.deleteMarker);
notesListActivity = (NotesListActivity) context;
listItem = listItems.get(getAdapterPosition());
notesListActivity.listItemsEditor(listItem, deleteMarker);
}
}
Речь идет о данном этапе deleteMarker = itemView.findViewById(R.id.deleteMarker);. При изменении видимости deleteMarker, изменяется видимость двух элементов, а именно выбранного и элемента который находится на расстоянии 10 элементов от него.
Ответы (2 шт):
Вы не учли что вью элементы переиспользуются. RecyclerView создаёт столько вью, сколько может быть видно на экране одновременно. А для отображения остальных данных используются те же самые вью - они просто перекладываются при прокрутке. Первая, которая скрылась, становится следующей, которая появляется.
Поэтому вы не должны ссылаться на вью, вместо этого нужно завязывать логику на позицию или содержимое данных.
Холдер не должен содержать метода onClick, т.к. ресайклер создает только ограниченное кол-во элементов (сколько помещается на экран + парочку за его пределами. это нужно для оптимизации UI и является основным отличием от ListView)
обработка кликов на элементы ресайкла обычно делается 2 способами:
в методе onBindViewHolder - считается мувитоном но рабочий вариант.
из минусов - onBindViewHolder вызывается каждый раз когда элемент пересоздается.
подходит, если у вас разная логика кликов на элементы.
если же логика клика на все карточки одинаковая, хорошим выбором будет прописать логику onClick в методе onCreateViewHolder
для этого, после созданий Холдера, но до его возврата используйте
holder.itemView.setOnClickListener
данный код отлично оптимизирован, т.к. в отличии от onBindViewHolder, который вызывается каждый раз, когда элемент показывается на экране, метод onCreateViewHolder сработает лишь 1 раз, когда карточка будет создаваться.