skip to Main Content

I’m creating a simple chat app wherein every chatbubbles will be shown in a RecyclerView, now I noticed that every time ill enter a new data coming from Firebase RealTime Database, the old data’s / or let’s say the old chat bubbles will disappear and reappear once the newly added data has been displayed. I would like the old chat bubbles to not behave just like that, I would like it to remain appeared the whole time.

Here’s my method to load every chatbubbles:

private void LoadChat() {


        Query orderPosts = ChatRef.orderByChild("servertimestamp");

        options = new FirebaseRecyclerOptions.Builder<Chat>().setQuery(orderPosts, Chat.class).build();
        adapter = new FirebaseRecyclerAdapter<Chat, MyViewHolder12>(options) {
            @Override
            protected void onBindViewHolder(@NonNull MyViewHolder12 holder, int position, @NonNull Chat model) {
                final String userpower = model.getPower();
                final String pow = "Admin";

                if (userpower.equals(pow)){
                    holder.chat_userpower.setVisibility(View.VISIBLE);
                    holder.chat_userpower.setText(model.getPower());

                }
                else{
                    holder.chat_userpower.setVisibility(View.GONE);
                }

                final String quotedc = model.getQuotedchat();
                final String quotedn = model.getQuotedname();

                if (quotedc == null){
                    holder.quotedchatbox.setVisibility(View.GONE);
                    holder.quotedchatboxlayout.setVisibility(View.GONE);
                    holder.quotedchatdescription.setVisibility(View.GONE);
                }
                else{
                    holder.quotedchatboxlayout.setVisibility(View.VISIBLE);
                    holder.quotedchatbox.setVisibility(View.VISIBLE);
                    holder.quotedchatdescription.setVisibility(View.VISIBLE);
                    holder.quotedchatdescription.setText("Quoted "+ model.getQuotedname() +" " + model.getQuotedchat());
                }


                holder.chat_usercomment.setText(model.getChat());
                Picasso.get().load(model.getProfileimage()).placeholder(R.drawable.profile).into(holder.chat_userimage);
                holder.chat_userdep.setText(model.getDep());
                holder.chat_date.setText(model.getDate());
                holder.chat_username.setText(model.getUsername());

                holder.nestedchat_reply.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        quote = true;
                        quotedname = model.getUsername();
                        //CommentKey = getRef(holder.getAdapterPosition()).getKey();
                        quoting.setVisibility(View.VISIBLE);
                        quotedchat = model.getChat();
                        quoting.setText("Quoting "+ quotedname + ": " + model.getChat());
                        quoting.setOnClickListener(new View.OnClickListener() {
                            @Override
                            public void onClick(View v) {
                                quote = false;
                                quoting.setVisibility(View.GONE);
                            }
                        });
                    }
                });

            }

            @NonNull
            @Override
            public MyViewHolder12 onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
                View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.allchatlayout, parent, false);
                return new MyViewHolder12(view);
            }
        };
        adapter.startListening();
        allchatlist.setAdapter(adapter);
    }

here’s my layoutmanager:

 LinearLayoutManager lm = new LinearLayoutManager(this);
        lm.setReverseLayout(false);
        lm.setStackFromEnd(false);
        allchatlist.setNestedScrollingEnabled(false);
        allchatlist.setLayoutManager(lm);

here’s my code calling the method:

 ChatRef = FirebaseDatabase.getInstance().getReference().child("Forums").child(ChatRoomNameKey).child("Forum ChatRoom");
        ChatRef.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot snapshot) {
                if (snapshot.exists()){
                    LoadChat();
                }
            }

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

            }
        });

2

Answers


  1. Chosen as BEST ANSWER

    I fixed the problem by removing the line:

     Query orderPosts = ChatRef.orderByChild("servertimestamp");
    
           options = new FirebaseRecyclerOptions.Builder<Chat>().setQuery(orderPosts, Chat.class).build();
    

    Removing that 2 lines of code from that method and putting it somewhere else inside the Activity fixed the blinking problem of my app when a new data has been added.


  2. To achieve that you will have to use RecyclerView DiffUtill class, more info here:

    https://developer.android.com/reference/androidx/recyclerview/widget/DiffUtil

    In a nutshell you have to create a diff util class:

    class CustomItemDiffUtils(
        private val oldList: List<CustomItem>,
        private val newList: List<CustomItem>
    ) : DiffUtil.Callback() {
    
        override fun getOldListSize(): Int = oldList.size
    
        override fun getNewListSize(): Int = newList.size
    
        override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
            return oldList[oldItemPosition] == newList[newItemPosition]
        }
    
        override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
            return oldList[oldItemPosition].data == newList[newItemPosition].data
        }
    }
    

    And use this diff class in your adapter fro example with a method which can be called from the view:

    fun updateList(newList: List<CustomItem>) {
            val diffResult = DiffUtil.calculateDiff(CustomItemDiffUtils(oldList, newList))
            oldList = newList
            diffResult.dispatchUpdatesTo(this)
        }
    

    Hope this helps.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search