Search code examples
androidfirebasefirebase-realtime-databaseandroid-recyclerviewfirebaseui

FirebaseUI Recycler View for Chat 2 Different Holder Not Applied Correctly AFTER Scrolling


I'm making a chat app. There are 2 views same viewholder. The problem is, when I scroll to the top, the image, name not correctly inserted as suppose. I'm using Firebase Ui Recycler View for Realtime Database.

firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<AdminMessage, AdminChatViewHolder>(firebaseRecyclerOptions) {
                @Override
                protected void onBindViewHolder(@NonNull final AdminChatViewHolder adminChatViewHolder, int i, @NonNull AdminMessage adminMessage) {

adminChatViewHolder.getTvMessage().setText(adminMessage.getMessage());



                //We retrieve the userUid to get real time name
                FirebaseDatabase.getInstance().getReference().child("admin").child(adminMessage.getSenderUid()).addListenerForSingleValueEvent(new ValueEventListener() {
                    @Override
                    public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                        if (dataSnapshot.exists()) {
                            Admin admin = dataSnapshot.getValue(Admin.class);
                            if (admin != null) {
                                final String nameAdmin = admin.getFullName();
                                final String profileUrl = admin.getProfileUrl();

                                //And then display
                                adminChatViewHolder.getTvName().setText(nameAdmin);

                                //Check for image if null or not (profileUrl)
                                if (profileUrl != null) {
                                    Glide.with(getApplicationContext())
                                            .load(profileUrl)
                                            .into(adminChatViewHolder.getImageView());
                                }
                            }
                        }
                    }

                    @Override
                    public void onCancelled(@NonNull DatabaseError databaseError) {

                    }
                });

            }


            @NonNull
            @Override
            public AdminChatViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
                View view;
                if (viewType == VT_SENDER) {
                    view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_admin_message_sender, parent, false);
                } else {
                    view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_admin_message_receiver, parent, false);
                }
                return new AdminChatViewHolder(view);
            }

            @Override
            public void onDataChanged() {
                progressBar.setVisibility(View.GONE);
            }

            @Override
            public int getItemViewType(int position) {
                if (getItem(position).getSenderUid().equals(userUid)) {
                    return VT_SENDER;
                }
                return VT_RECEIVER;
            }
        };

Solution

  • Alright, I remember I had the same issue before. I will try to remember all I can and update this answer.

    Always empty the image view or hide it when there isn't an image or url fails:

    if (profileUrl != null) {
       Glide.with(getApplicationContext())
            .load(profileUrl)
            .into(adminChatViewHolder.getImageView());
    }
    else
    {
      //TODO: set an image place holder or hide adminChatViewHolder.getImageView()
    }
    

    I like to empty the imageView while waiting for the new one to load and do the same for all views not just imageView (i.e. textview) What if admin is null? what happens?

    Don't forget to call super.onDataChanged();