Элементы RecyclerView не отображаются правильно
В моем onBindViewHolder
моего RecyclerView.Adapter<SearchAdapter.ViewHolder>
, когда пользователь нажимает кнопку cardview
, кнопка становится видимой. Но когда я прокручиваю recyclerview, некоторые другие кнопки элементов отображаются как видимые тоже. Почему это происходит?
это мой код:
@Override
public void onBindViewHolder(final ViewHolder viewHolder, final int position) {
viewHolder.card.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (viewHolder.content_layout.getVisibility() == View.VISIBLE) {
viewHolder.content_layout.setVisibility(View.GONE);
viewHolder.address.setMaxLines(2);
viewHolder.attribute.setMaxLines(2);
} else {
viewHolder.content_layout.setVisibility(View.VISIBLE);
viewHolder.address.setMaxLines(8);
viewHolder.attribute.setMaxLines(8);
}
}
});
...
}
Ответы
Ответ 1
Как только вы начнете прокрутку списка, ваши просмотры будут переработаны. Это означает, что ранее завышенный ViewHolder (некоторые из которых создаются в onCreateViewHolder
) повторно используется.
Итак, вам нужно запомнить защёщенные позиции (например, через SparseBooleanArray) и проверить onBindViewHolder
, следует ли быть видимым (ранее нажатым) или нет.
Вы можете найти базовый пример использования SparseBooleanArray
в fooobar.com/questions/128033/...
Ответ 2
Кнопки "других" видимых элементов - те, которые используются одним и тем же наблюдателем, который был изменен в обратном вызове. Таким образом, поскольку пользователи (и представления) переработаны:
-
Они должны хранить информацию, которая может быть получена каждый раз, когда зритель привязан к позиции.
-
Все, что может быть изменено в состоянии представлений, должно быть обновлено в onBindViewHolder()
В вашем случае вы должны сохранить 'selected' в другом месте и reset видимость и максимальные значения в onBindViewHolder()
(не только в обратном вызове)
Ответ 3
Хорошей идеей является создание объекта класса со всеми данными, которые вам нужны для одного элемента в представлении recycler, а также добавить туда один логический isItemWasClicked
и внутри onBindViewHolder()
проверить это логическое и сделать кнопки видимыми или нет.
Например:
public class OneItemOfList{
int priceToDisplay;
String name;
String date;
boolean wasClicked;
}
public class YourAdapter extends RecyclerView.Adapter<OneItemOfList.ViewHolder> {
ArrayList<OneItemOfList> items;
...
@Override
public void onBindViewHolder(ViewHolder viewHolder, final int position) {
viewHolder.view.setText(items.get(position).name);
if (items.get(position).wasClicked)
viewHolder.button.setVisible(View.VISIBLE);
else
viewHolder.button.setVisible(View.GONE);
viewHolder.view2.setOnClickListener(...
OnClick(...){
items.get(position).wasClicked = !items.get(position).wasClicked;
});
}
...
}
Ответ 4
создайте массив, например Boolean array, и когда каждая позиция нажата, установите true в том же положении массива. и в onBindViewHolder проверьте, установлен ли этот массив [позиция] true, чтобы этот элемент был видимым, если.