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.