Почему адаптер Recyclerview onBindViewHolder вызывается более одного раза?
Я использую это руководство для реализации DiffUtil в моем обзоре утилит. Моя цель состоит в том, чтобы добавить один элемент в конец окна повторного просмотра, не перезагружая оставшуюся часть повторного просмотра. Я использовал fireStore addSnapshotListener для вызова адаптера. Проблема заключается в onBindViewHolder
вызывается несколько раз (т. е. в списке нет ни одного элемента). Я не думаю, что это должно произойти при использовании DiffUtil, верно? Он должен вызывать onBindViewHolder только для элемента, добавляемого в утилита-просмотр, верно?
Вот код, который я называю адаптером:
@Override
protected void onStart()
{
super.onStart();
reference
.addSnapshotListener((Activity)context, new EventListener<QuerySnapshot>()
{
@Override
public void onEvent(@Nullable QuerySnapshot queryDocumentSnapshots,
@Nullable FirebaseFirestoreException e)
{
if (e != null)
{
Toast.makeText(context, "Error", Toast.LENGTH_SHORT).show();
return;
}
CommentsListAdapter adapter = new CommentsListAdapter(context);
commentsRecyclerView.setAdapter(adapter);
comments = new ArrayList<>();
for (QueryDocumentSnapshot snapshot : queryDocumentSnapshots)
{
Comment comment = snapshot.toObject(Comment.class).withId(snapshot.getId());
comments.add(comment);
}
adapter.submitList(comments);
commentsRecyclerView.smoothScrollToPosition(adapter.getItemCount());
}
});
}
Это класс адаптера:
class CommentsListAdapter extends ListAdapter<Comment, CommentsListAdapter.CommentsViewHolder>
{
private Context context;
protected CommentsListAdapter(Context context)
{
super(DIFF_CALLBACK);
this.context = context;
}
private static final DiffUtil.ItemCallback<Comment> DIFF_CALLBACK = new DiffUtil.ItemCallback<Comment>()
{
@Override
public boolean areItemsTheSame(@NonNull Comment oldItem, @NonNull Comment newItem)
{
return oldItem.commentId.equals(newItem.commentId);
}
@Override
public boolean areContentsTheSame(@NonNull Comment oldItem, @NonNull Comment newItem)
{
return oldItem.commentId.equals(newItem.commentId);
}
};
@NonNull
@Override
public CommentsViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType)
{
View itemView = LayoutInflater.from(context)
.inflate(R.layout.comment_list_item, parent, false);
return new CommentsViewHolder(itemView);
}
@Override
public void onBindViewHolder(@NonNull final CommentsViewHolder holder, int position)
{
System.out.println("POSITION: " + position);
holder.commentText.setText(getItem(position).getComment());
holder.timeText.setText(getItem(position).getCommentDateCreated());
}
public class CommentsViewHolder extends RecyclerView.ViewHolder
{
private TextView commentText;
private TextView timeText;
public CommentsViewHolder(@NonNull View itemView)
{
super(itemView);
commentText = itemView.findViewById(R.id.commentText);
timeText = itemView.findViewById(R.id.timeText);
}
}
}
Я новичок в DiffUtil. Итак, это должно произойти? Или что-то не так с кодом?
1 ответ
Каждый раз, когда вы получаете обратный вызов из Firestore, вы воссоздаете свой CommentsListAdapter
Вставьте адаптер в глобальную переменную в вашей деятельности и вызовите только adapter.submitList(comments);
в обратном вызове Firestore
Ваш отредактированный код:
CommentsListAdapter adapter = new CommentsListAdapter(context);
@Override
protected void onStart()
{
super.onStart();
commentsRecyclerView.setAdapter(adapter);
reference
.addSnapshotListener((Activity)context, new EventListener<QuerySnapshot>()
{
@Override
public void onEvent(@Nullable QuerySnapshot queryDocumentSnapshots,
@Nullable FirebaseFirestoreException e)
{
if (e != null)
{
Toast.makeText(context, "Error", Toast.LENGTH_SHORT).show();
return;
}
comments = new ArrayList<>();
for (QueryDocumentSnapshot snapshot : queryDocumentSnapshots)
{
Comment comment = snapshot.toObject(Comment.class).withId(snapshot.getId());
comments.add(comment);
}
adapter.submitList(comments);
commentsRecyclerView.smoothScrollToPosition(adapter.getItemCount());
}
});
}