简体   繁体   English

活动重启后Recyclerview不更新

[英]Recyclerview not updating after activity restart

So, I'm not sure about the title of this question but here it goes.所以,我不确定这个问题的标题,但它就在这里。 I have a recyclerview for my chat room.我的聊天室有一个 recyclerview。 The first time the activity started it has no problem displaying the messages but after pressing the back button back to the main activity showing all chat rooms then click the same chat room again it displays nothing.活动第一次启动时,显示消息没有问题,但是在按下后退按钮回到显示所有聊天室的主要活动后,再次单击同一个聊天室,它什么也不显示。 Then, after sent a message it can display all the messages again.然后,发送一条消息后,它可以再次显示所有消息。 I'm not sure what happened, help, please.我不确定发生了什么,请帮助。 Oh, I already tried a few things and browse the internet but because I'm not sure what the keyword is, so I'm quite stuck now哦,我已经尝试了一些东西并浏览了互联网,但是因为我不确定关键字是什么,所以我现在很卡住

Okay, here is the thing好的,事情就是这样

First main activity, (ignore the other 2 tabs, it's empty)第一个主要活动,(忽略其他 2 个选项卡,它是空的)

Main Activity主要活动

Then open a chat room然后开个聊天室

First time open chat room fine第一次打开聊天室没问题

Then press back button, back to MainActivity, then open the same room and no chat displayed然后按返回键,回到MainActivity,然后打开同一个房间,没有聊天显示

chat room not displaying anything聊天室不显示任何内容

Then it displays messages again after sending a new messages然后它在发送新消息后再次显示消息

new message新消息

I have tried to place notifyDataSetChanged() on various event like onStart, onCreate etc but nothing works;我试图将 notifyDataSetChanged() 放在 onStart、onCreate 等各种事件上,但没有任何效果;

here is my chat activity这是我的聊天活动

package com.divistant.chat.ui.chat;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.ScrollView;
import android.widget.TextView;

import com.divistant.chat.R;
import com.divistant.signup.UserModel;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.database.ChildEventListener;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import com.google.gson.Gson;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class ChatActivity extends AppCompatActivity {
    LinearLayout layout;
    ImageView send;
    EditText message;
    ScrollView scrollView;
    DatabaseReference refrence1;
    DatabaseReference refrence2;
    RecyclerView rv;
    List<ChatModel> chats = new ArrayList<>();
    ChatActivityAdapter adapter;

    FirebaseUser cUser;
    UserModel target;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_chat);
        Log.w("EVENT","ON Create");

        Intent intent = getIntent();
        target = (new Gson()).fromJson(intent.getStringExtra("target"),UserModel.class);

        send = (ImageView)findViewById(R.id.sendButton);
        message = (EditText)findViewById(R.id.messageArea);
        scrollView = (ScrollView)findViewById(R.id.scrollView);
        rv = (RecyclerView) findViewById(R.id.main_chat_rv);
        cUser = FirebaseAuth.getInstance().getCurrentUser();
        adapter = new ChatActivityAdapter(chats);

        final LinearLayoutManager manager = new LinearLayoutManager(ChatActivity.this,
                LinearLayoutManager.VERTICAL, false);
        rv.setLayoutManager(manager);


        refrence1 = FirebaseDatabase.getInstance()
                .getReference()
                .child("messages")
                .child(cUser.getUid() + "_" + target.getUserId());

        refrence2 = FirebaseDatabase.getInstance()
                .getReference()
                .child("messages")
                .child(target.getUserId() + "_" + cUser.getUid());

        send.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                Log.w("SEND","send message");

                if(message.getText().toString().length() > 0){
                    ChatModel chat = new ChatModel();
                    chat.setSender(cUser.getEmail());
                    chat.setMessage(message.getText().toString());
                    chat.setReceiver(target.getEmailAddress());
                    chat.setSenderUid(cUser.getUid());
                    chat.setReceiverUid(target.getUserId());
                    chat.setTimestamp((new Date()).getTime());
                    DatabaseReference ref1 = refrence1.push();
                    ref1.setValue(chat);
                    DatabaseReference ref2 = refrence2.push();
                    ref2.setValue(chat);

                    message.setText("");
                }
            }
        });



        refrence1.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                chats.clear();

                for(DataSnapshot snapshot :dataSnapshot.getChildren()){
                    ChatModel chat = new ChatModel();
                    chat.setSender(snapshot.child("sender").getValue(String.class));
                    chat.setMessage(snapshot.child("message").getValue(String.class));
                    chat.setReceiver(snapshot.child("receiver").getValue(String.class));
                    chat.setSenderUid(snapshot.child("senderUid").getValue(String.class));
                    chat.setReceiverUid(snapshot.child("receiverUid").getValue(String.class));
                    chat.setTimestamp(1592455659978L);

                    chats.add(chat);
                }
                adapter.setmChats(chats);
                adapter.notifyDataSetChanged();
                rv.scrollToPosition(adapter.getItemCount()-1);
                Log.e("[CH]","DATACHANGE " + chats.size());
            }



            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {
                Log.e("[CH]","CANCEL");
            }
        });

        refrence1.addChildEventListener(new ChildEventListener() {
            @Override
            public void onChildAdded(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
                chats.clear();
                adapter.notifyDataSetChanged();
                rv.scrollToPosition(adapter.getItemCount()-1);
            }

            @Override
            public void onChildChanged(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
                Log.e("[CH]","DB CHANGE");
            }

            @Override
            public void onChildRemoved(@NonNull DataSnapshot dataSnapshot) {
                Log.e("[CH]","DB REMOVE");
            }

            @Override
            public void onChildMoved(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
                Log.e("[CH]","Child Moved");
            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {
                Log.e("[CH]","DB ERROR");
            }
        });


        rv.setAdapter(adapter);

    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.e("[CH]","" + adapter.getItemCount());
    }
}

Then, here is my ChatActivityAdapter然后,这是我的 ChatActivityAdapter

package com.divistant.chat.ui.chat;

import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import com.divistant.chat.R;
import com.google.firebase.auth.FirebaseAuth;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class ChatActivityAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{
    private static final int VIEW_TYPE_ME = 1;
    private static final int VIEW_TYPE_OTHER = 2;
    List<ChatModel> mChats;


    public void setmChats(List<ChatModel> mChats) {
        this.mChats = mChats;
    }

    public ChatActivityAdapter(List<ChatModel> mChats) {
        this.mChats = mChats;
        Log.e("ADAPTER","CONSTRUCTED " + mChats.size());
    }

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
        RecyclerView.ViewHolder viewHolder = null;
        switch (viewType) {
            case VIEW_TYPE_ME:
                View viewChatMine = layoutInflater.inflate(R.layout.chat_item, parent, false);
                viewHolder = new MyChatViewHolder(viewChatMine);
                break;
            case VIEW_TYPE_OTHER:
                View viewChatOther = layoutInflater.inflate(R.layout.chat_item_other, parent, false);
                viewHolder = new OtherChatViewHolder(viewChatOther);
                break;
        }
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
        if (TextUtils.equals(mChats.get(position).senderUid,
                FirebaseAuth.getInstance().getCurrentUser().getUid())) {
            configureMyChatViewHolder((MyChatViewHolder) holder, position);
        } else {
            configureOtherChatViewHolder((OtherChatViewHolder) holder, position);
        }
    }
    private void configureMyChatViewHolder(final MyChatViewHolder myChatViewHolder, int position) {
        ChatModel chat = mChats.get(position);
        SimpleDateFormat sfd = new SimpleDateFormat("hh:mm a");
        String date=sfd.format(new Date(chat.timestamp).getTime());
        myChatViewHolder.senderMsgTime.setText(date);
        myChatViewHolder.txtChatMessage.setText(chat.getMessage());
    }

    private void configureOtherChatViewHolder(final OtherChatViewHolder otherChatViewHolder, int position) {
        final ChatModel chat = mChats.get(position);
        SimpleDateFormat sfd = new SimpleDateFormat("hh:mm a");
        String date=sfd.format(new Date(chat.timestamp).getTime());
        otherChatViewHolder.receiverMsgTime.setText(date);
        otherChatViewHolder.txtChatMessage.setText(chat.getMessage());
    }

    @Override
    public int getItemCount() {
        return mChats.size();
    }

    @Override
    public int getItemViewType(int position) {
        if (TextUtils.equals(mChats.get(position).senderUid,
                FirebaseAuth.getInstance().getCurrentUser().getUid())) {
            return VIEW_TYPE_ME;
        } else {
            return VIEW_TYPE_OTHER;
        }
    }

    private static class MyChatViewHolder extends RecyclerView.ViewHolder {
        private TextView txtChatMessage, txtUserAlphabet;
        private TextView senderMsgTime;

        public MyChatViewHolder(View itemView) {
            super(itemView);
            txtChatMessage = (TextView) itemView.findViewById(R.id.text_view_chat_message);
            txtUserAlphabet = (TextView) itemView.findViewById(R.id.text_view_user_alphabet);
            senderMsgTime=(TextView) itemView.findViewById(R.id.senderMsgTime);
        }
    }

    private static class OtherChatViewHolder extends RecyclerView.ViewHolder {
        private TextView txtChatMessage, txtUserAlphabet;
        private TextView receiverMsgTime;

        public OtherChatViewHolder(View itemView) {
            super(itemView);
            txtChatMessage = (TextView) itemView.findViewById(R.id.text_view_chat_message_ot);
            txtUserAlphabet = (TextView) itemView.findViewById(R.id.text_view_user_alphabet_ot);
            receiverMsgTime=(TextView) itemView.findViewById(R.id.receiverMsgTime_ot);
        }
    }




}

Thanks谢谢

Thats because you are clearing the list on childevent listener and not adding the new child in list and not passing the list to the adapter.那是因为您正在清除子事件侦听器上的列表,而不是在列表中添加新的孩子,也没有将列表传递给适配器。

 @Override
        public void onChildAdded(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
            chats.clear();
            adapter.notifyDataSetChanged();
            rv.scrollToPosition(adapter.getItemCount()-1);
        }

Now change the code by adding the lines现在通过添加行来更改代码

 @Override
        public void onChildAdded(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
            chats.clear();
            for(DataSnapshot snapshot :dataSnapshot.getChildren()){
                ChatModel chat = new ChatModel();
                chat.setSender(snapshot.child("sender").getValue(String.class));
                chat.setMessage(snapshot.child("message").getValue(String.class));
                chat.setReceiver(snapshot.child("receiver").getValue(String.class));
                chat.setSenderUid(snapshot.child("senderUid").getValue(String.class));
            chat.setReceiverUid(snapshot.child("receiverUid").getValue(String.class));
                chat.setTimestamp(1592455659978L);

                chats.add(chat);
            }
            adapter.setmChats(chats);
            adapter.notifyDataSetChanged();
            rv.scrollToPosition(adapter.getItemCount()-1);
        }

in my case i used onResume()就我而言,我使用了onResume()

  @Override
    protected void onResume() {
        super.onResume();
         adapter.notifyDataSetChanged();
    }

Can you put rv.setAdapter(adapter) after rv.setLayoutManager(manager);?你能把 rv.setAdapter(adapter) 放在 rv.setLayoutManager(manager); 之后吗? And you verify if the method onDataChange(...) its always called??并且您验证是否始终调用 onDataChange(...) 方法?

You can use the following code in the adapter where you want to refresh recyclerview, for example in @Override public void onBackPressed(){} function.您可以在要刷新 recyclerview 的适配器中使用以下代码,例如在@Override public void onBackPressed(){} function 中。 If your chats array changed, you should refresh this adapter.如果你的 chats 数组改变了,你应该刷新这个适配器。

mAdapter = new ChatActivityAdapter(context, chats.get(chats.size() - 1), chats);
recyclerView.setAdapter(mAdapter);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM