Home > Enterprise >  How to prevent RecyclerView from refreshing all the datas when a newly data has been added?
How to prevent RecyclerView from refreshing all the datas when a newly data has been added?

Time:11-04

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) {

            }
        });

CodePudding user response:

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.

CodePudding user response:

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.

  • Related