我正在使用此方法加载活跃用户:
private void loadActiveUsers() {
usersList.clear();
Query activeUsersQuery = firebaseFirestore.collection("Users").whereEqualTo("active", true);
activeUsersQuery.addSnapshotListener(new EventListener<QuerySnapshot>() {
@Override
public void onEvent(@Nullable QuerySnapshot queryDocumentSnapshots, @Nullable FirebaseFirestoreException e) {
for (DocumentChange documentChange: queryDocumentSnapshots.getDocumentChanges()) {
if (documentChange.getType() == DocumentChange.Type.ADDED) {
String user_id = documentChange.getDocument().getId();
Users users = documentChange.getDocument().toObject(Users.class).withId(user_id);
usersList.add(users);
activeUsersRecyclerAdapter.notifyDataSetChanged();
}
if (documentChange.getType() == DocumentChange.Type.MODIFIED) {
String user_id = documentChange.getDocument().getId();
Users users = documentChange.getDocument().toObject(Users.class).withId(user_id);
usersList.remove(users);
usersList.clear();
usersList.add(users);
activeUsersRecyclerAdapter.notifyDataSetChanged();
}
if (documentChange.getType() == DocumentChange.Type.REMOVED) {
String user_id = documentChange.getDocument().getId();
Users users = documentChange.getDocument().toObject(Users.class).withId(user_id);
usersList.remove(users);
activeUsersRecyclerAdapter.notifyDataSetChanged();
}
}
}
});
}
新用户启用后,其名称将添加到列表中,但是会多次添加。单击刷新按钮后,列表将恢复正常。如果他不活动,则recyclerview会混乱。
这是适配器:
public class ActiveUsersRecyclerAdapter extends RecyclerView.Adapter<ActiveUsersRecyclerAdapter.ViewHolder> {
public List<Users> usersList;
public Context context;
public ActiveUsersRecyclerAdapter(Context context, List<Users> usersList) {
this.context = context;
this.usersList = usersList;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int i) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.user_list_item, parent, false);
context = parent.getContext();
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
final String userID = usersList.get(position).UserID;
String image = usersList.get(position).getImage();
holder.setImage(image);
String username = usersList.get(position).getUsername();
holder.setUsername(username);
holder.view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(context, userID, Toast.LENGTH_SHORT).show();
}
});
}
@Override
public int getItemCount() {
return usersList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public View view;
public CircleImageView imageView;
public TextView usernameView;
public ViewHolder(@NonNull View itemView) {
super(itemView);
view = itemView;
}
public void setImage(String image) {
imageView = view.findViewById(R.id.user_image);
Glide.with(context).load(image).into(imageView);
}
public void setUsername(String username) {
usernameView = view.findViewById(R.id.user_username);
usernameView.setText(username);
}
}
}
我尝试了holder.setIsRecyclable(false)
,但是没有用。
如何防止多次添加数据或阻止回收者搞乱?
答案 0 :(得分:0)
调用addSnapshotListener
时,您正在向数据添加永久侦听器。当您附加侦听器时,它会立即开始加载数据并调用onEvent
,但是如果有任何相关更改(例如,当另一个用户变为活动状态时),它也会继续主动监视数据并再次调用onEvent
。 。因此,如果您使用addSnapshotListener
,则无需多次拨打loadActiveUsers
。
如果只想在调用loadActiveUsers
时加载活动用户,请考虑改用get()
方法。调用get()
时,数据仅一次加载一次。因此,在这种情况下,只要用户单击刷新以加载更新的数据,就可以调用loadActiveUsers
。
一般而言,我还是建议使用addSnapshotListener
,因为它会使您的UI响应数据中的更改(无论它们来自何处)。但是在那种情况下,请确保仅将侦听器附加一次(通常在创建活动时),并在完成后将其删除(通常在活动停止,暂停或隐藏时)。