В моем приложении RecyclerView
работает с FirestoreRecyclerAdapter
. В ViewHolders
реализовано расширяемое меню «быстрых действий», которое расширяется при нажатии на элемент, и идеальным поведением является расширение только одного элемента за раз. Развертывание одного элемента должно свернуть все остальные элементы в адаптере.
Когда на экране достаточно предметов, чтобы разместить их все, это работает отлично. Но если список расширяется за пределы экрана, когда я пытаюсь перебрать элементы адаптера, я получаю NullPointerException
, когда отсоединенные или неэкранные ViewHolders пытаются вызвать getParent()
.
Как я могу перебрать все ViewHolders в адаптере или, альтернативно, перебрать только видимые?
Соответствующий код адаптера:
@Override
protected void onBindViewHolder(@NonNull BrewViewHolder holder,
int position, @NonNull Brew brew) {
// Bind Views
holder.bind(brew);
// Set expander ClickListener
holder.card.setOnClickListener(v -> {
for (int i = 0; i < mAdapter.getItemCount(); i++) {
if (i != position) {
// ERROR THROWN HERE
BrewViewHolder vh = ((BrewViewHolder) recyclerView.getChildViewHolder(recyclerView.getChildAt(i)));
vh.expanded = false;
}
}
holder.expanded = !holder.expanded;
notifyItemChanged(position);
});
}
Соответствующий код ViewHolder:
public class BrewViewHolder extends RecyclerView.ViewHolder {
// Expanded state
public boolean expanded = false;
...
public BrewViewHolder(@NonNull final View itemView) {
super(itemView);
...
// Set visibility of quick actions based on expanded state
quickActions.setVisibility(expanded ? View.VISIBLE : View.GONE);
}
}
Заранее спасибо!
РЕДАКТИРОВАТЬ: Как указал Гилберто , это очень дорого. Пошел с версией решения Andrew :
private int expandedItemIndex = -1;
@Override
protected void onBindViewHolder(@NonNull BrewViewHolder holder, int position,
@NonNull Brew brew) {
// Bind Views
holder.bind(brew);
// Set expander ClickListener
holder.card.setOnClickListener(v -> {
if (position == expandedItemIndex) {
holder.expanded = false;
expandedItemIndex = -1;
} else {
holder.expanded = true;
if (expandedItemIndex != -1) {
BrewViewHolder otherHolder = ((BrewViewHolder) recyclerView.getChildViewHolder(
recyclerView.getChildAt(expandedItemIndex)));
otherHolder.expanded = false;
}
expandedItemIndex = position;
}
notifyItemRangeChanged(0, recyclerView.getChildCount());
});
}