简体   繁体   English

notifydatasetchanged后recyclerview不更新

[英]recyclerview not updating after notifydatasetchanged

I have chat fragment which is backed by recyclerview. 我有由recyclerview支持的聊天片段。 When i enter chat screen manually to send or receive message its work fine. 当我手动进入聊天屏幕以发送或接收消息时,它的工作正常。 but when i closed app and enter app from message notification, Its sending message to other user but not updating own recyclerview. 但是,当我关闭应用程序并从消息通知中输入应用程序时,它会向其他用户发送消息,但不会更新自己的recyclerview。

Chat Fragment 聊天片段

public class Chat_Screen_Fragment extends Fragment implements View.OnClickListener, ChildEventListener{

    public static final String TAG = "###CHAT SCREEN###";

    List<Chat_Wrapper> message = new ArrayList<>();


    Chat_Adapter adapter;
    RecyclerView recyclerView;
    LinearLayoutManager layoutManager;


    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
        View v=inflater.inflate(R.layout.chat_screen_main_fragment,container,false);
        setRetainInstance(true);



        // GET INTENT VALUES FROM USER PROFILE CLASS

        UserName_Intent = getArguments().getString("Get_Name");
        UserImage_Intent = getArguments().getString("Get_Image");
        UserPhone_Intent = getArguments().getString("Get_Phone");
        UserID_Intent = getArguments().getString("Get_ID");
        FirebaseToken_Intent = getArguments().getString("Get_Token"); //Firebase Token of other person
        Room_Name_Intent = getArguments().getString("Get_Other"); // Room Name of chat
        UserLastSeen_Intent=getArguments().getString("LastSeen");
        //Sender_FCMToken = Session.getFirebaseID();







        // RECYCLER VIEW
        recyclerView = v.findViewById(R.id.Chat_Screen_Message_List);
        layoutManager = new LinearLayoutManager(getActivity());
        layoutManager.setStackFromEnd(true);
        recyclerView.setHasFixedSize(true);
        recyclerView.setLayoutManager(layoutManager);
databaseReference = FirebaseDatabase.getInstance().getReference().child(Room_Name_Intent);
        databaseReference.addChildEventListener(this);

        adapter = new Chat_Adapter(getActivity(), message);
        recyclerView.setAdapter(adapter);
        // FETCH OLD MESSAGE FROM DATABASE
        chatDatabase();
        return v;
    }



    // FIREBASE REAL TIME DATABASE WHICH FETCH ALL MESSAGES (SYNC) FROM ONLINE DATABASE
    @Override
    public void onChildAdded(DataSnapshot dataSnapshot, String s) {
        append_chat_conversation(dataSnapshot);
    }

    @Override
    public void onChildChanged(DataSnapshot dataSnapshot, String s) {
        append_chat_conversation(dataSnapshot);
    }

    @Override
    public void onChildRemoved(DataSnapshot dataSnapshot) {

    }

    @Override
    public void onChildMoved(DataSnapshot dataSnapshot, String s) {

    }

    @Override
    public void onCancelled(DatabaseError databaseError) {

    }




    //THIS METHOD WILL FETCH ADD ALL MESSAGES FROM FIREBASE DATABASE AND ALSO SEARCH RESULT
    private synchronized void append_chat_conversation(DataSnapshot dataSnapshot) {
        iterator = dataSnapshot.getChildren().iterator();


        while (iterator.hasNext()) {
            // NOW GET ALL DATA FROM FIREBASE DATABASE AND SAVE IT INTO STRINGS THEN CHECK EACH BY ITS MESSAGE TYPE
            Chat_Msg = (String) ((DataSnapshot) iterator.next()).getValue();
            Chat_FROM = (String) ((DataSnapshot) iterator.next()).getValue();
            Chat_FCM_TO= (String) ((DataSnapshot) iterator.next()).getValue();

            Chat_Database tempChatDatabase = new Chat_Database(getActivity());
            boolean hasValue=tempChatDatabase.CheckValueExist(_ID);


            if (!hasValue) {
                Log.d(TAG,"Chat Message "+Chat_Msg);


                    long id=chat_database.Insert_Chat(Session.getUserID(),Room_Name_Intent, UserID_Intent, "Text", Chat_Msg, Chat_FROM, Chat_TO, Chat_TimeStamp, Chat_FCM_FROM, Chat_FCM_TO, Session.getPhoneNO(), UserPhone_Intent,Random_ID,UserImage_Intent,UserLastSeen_Intent,Chat_FROM_ID);

                    //Adding Chat Data Into Database
                    Log.d(TAG,"Database Entry ID "+id);
                    if (id==0){
                        Log.d(TAG,"Database Already Has Value Of This Random Id ");
                        return;
                    }
                    Chat_Wrapper chat_wrapper = new Chat_Wrapper(Chat_Msg, null, null, null, null, null, null, Chat_TimeStamp, User_Intent, UserImage_Intent, Chat_FROM, null,null,id);
                    message.add(chat_wrapper);
                  adapter.notifyDataSetChanged();
                Log.d(TAG, "FIREBASE STORAGE PHOTO-3-MESSAGE ARRAY SIZE " + message.size());
                recyclerView.post(new Runnable() {
                    @Override
                    public void run() {
                        Log.d(TAG, "Moving to Bottom");
                        recyclerView.smoothScrollToPosition(adapter.getItemCount());

                    }
                });

                }               

                }

            }

            Log.d(TAG, "MESSAGE ARRAY SIZE " + message.size());

            tempChatDatabase.isDatabaseClose();
        }

        adapter.notifyDataSetChanged();
        recyclerView.post(new Runnable() {
            @Override
            public void run() {
                Log.d(TAG, "Moving to Bottom");
                recyclerView.smoothScrollToPosition(message.size()-1);
                //recyclerView.smoothScrollToPosition(adapter.getItemCount());

            }
        });
    }



    private void chatDatabase(){
        //Database Init and Filling Adapter
        Log.d(TAG,"Chat Database Function");
        chat_database=new Chat_Database(getActivity());
        chatCursor=chat_database.getUserChat(UserID_Intent);
        boolean checkDB_Exist=functions.DatabaseExist(getActivity(),"CHAT_DATABASE.DB");
        boolean chatItemsCounts=chatCursor.getCount()>0;
        chatCursor.moveToFirst();
        Log.d(TAG,"Value At Chat Database "+ checkDB_Exist+" "+chatItemsCounts);
        if (checkDB_Exist && chatCursor.getCount()>0 && chatCursor.getString(chatCursor.getColumnIndex("RECEIVER_USER_ID")).equals(UserID_Intent)){

            Log.d(TAG,"Database Exist Chat Database");
            message.clear();
            chatCursor.moveToFirst();
            do {
                database_rowID=chatCursor.getInt(chatCursor.getColumnIndex("ID"));
                database_userID=chatCursor.getString(chatCursor.getColumnIndex("USER_ID"));
                database_RoomName =chatCursor.getString(chatCursor.getColumnIndex("ROOM_NAME"));
                database_ReceiverID=chatCursor.getString(chatCursor.getColumnIndex("RECEIVER_USER_ID"));
                database_MessageType=chatCursor.getString(chatCursor.getColumnIndex("MESSAGE_TYPE"));
                database_Message=chatCursor.getString(chatCursor.getColumnIndex("USER_MESSAGE"));
                database_MsgFrom=chatCursor.getString(chatCursor.getColumnIndex("SENDER_NAME"));
                database_MsgTo=chatCursor.getString(chatCursor.getColumnIndex("RECEIVER_NAME"));
                database_TimeStamp=chatCursor.getString(chatCursor.getColumnIndex("TIME_STAMP"));
                database_FCMfrom=chatCursor.getString(chatCursor.getColumnIndex("SENDER_TOKEN"));
                database_FCMto=chatCursor.getString(chatCursor.getColumnIndex("RECEIVER_TOKEN"));
                database_LocalPath=chatCursor.getString(chatCursor.getColumnIndex("DOWNLOADED_AT"));
                database_PhoneFrom=chatCursor.getString(chatCursor.getColumnIndex("MY_PHONE"));
                database_PhoneTo=chatCursor.getString(chatCursor.getColumnIndex("OTHER_PHONE"));

                Log.d(TAG,"Value Of Database Message String = "+database_Message);
                Log.d(TAG,"Row ID of Database "+database_rowID);
                // Check Message Type


                    Log.d(TAG,"Message Type Is Text");
                    Chat_Wrapper text = new Chat_Wrapper(database_Message, null, null, null, null, null, null, database_TimeStamp, database_PhoneTo, UserImage_Intent, database_MsgFrom,null,null,database_rowID);
                    message.add(text);



            }
            while(chatCursor.moveToNext());

            Room_Name_Intent = database_RoomName;
            layoutManager = new LinearLayoutManager(getActivity());
            recyclerView.setLayoutManager(layoutManager);
            adapter.notifyDataSetChanged();
            chatCursor.close();
            boolean value = chat_database.isDatabaseClose();
            recyclerView.post(new Runnable() {
                @Override
                public void run() {
                    Log.d(TAG, "Moving to Bottom");
                    recyclerView.smoothScrollToPosition(message.size()-1);

                }
            });
            Log.d(TAG,"Value Of Database Close or Not "+value);

        }
    }
}

Chat Adapter 聊天适配器

public class Chat_Adapter extends RecyclerView.Adapter<Chat_Adapter.ViewHolder> {

public static final String TAG="###CHAT_ADAPTER###";
private Context context;
Chat_Database database;
Chat_Wrapper chat_wrapper;


public Chat_Adapter(Context context, List<Chat_Wrapper> message) {
    this.context = context;
    this.arrayList_message = message;

}


@Override
public Chat_Adapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View Layout;
    Log.d(TAG,"On Create View Holder Calling ");
    if (viewType==1){
        Log.d(TAG,"View Tyoe Is "+viewType);
        Layout=LayoutInflater.from(parent.getContext()).inflate(R.layout.chat_screen_message_item,parent,false);
      //  ImagePath=Session.getUserImage();
    }
    else {
        Log.d(TAG,"View Type Is "+viewType);
        Layout=LayoutInflater.from(parent.getContext()).inflate(R.layout.chat_screen_message_item_other,parent,false);
       // ImagePath=chat_wrapper.getImageView();
    }

    return new ViewHolder(Layout);
}

@Override
 public void onBindViewHolder(final Chat_Adapter.ViewHolder holder, final int position) {
    chat_wrapper=arrayList_message.get(position);
    database=new Chat_Database(context);

        holder.Message.setVisibility(View.VISIBLE);
        holder.TimeStamp.setVisibility(View.VISIBLE);
        holder.User_Image.setVisibility(View.VISIBLE);

        //CHECK SENDER IS SAME AS LOGGED IN USER
        if ((Session.getUserFname()+" "+Session.getUserLname()).equals(chat_wrapper.getSender_UserName())){
            ImagePath=Session.getUserImage();
            Log.d(TAG,"Session.getUserImage() "+Session.getUserImage());
            Log.d(TAG,"Value Of Message Running ImagePath "+ImagePath);

        }
        else {
            //String filePath="/data/data/com.boysjoys.com.pro_working1/my_picture.jpg"
            ImagePath=chat_wrapper.getImageView();

            Log.d(TAG,"Value Of Message Running ImagePath "+ImagePath);
        }

        holder.Message.setText(chat_wrapper.getMessage());
        holder.TimeStamp.setText(chat_wrapper.getTimestamp());
        holder.TimeStamp.setVisibility(View.GONE);
        Glide.with(MyApplication.getmContext())
                .load(ImagePath)
                .apply(new RequestOptions()
                        .diskCacheStrategy(DiskCacheStrategy.ALL)
                        .fitCenter().skipMemoryCache(false))
                .into(holder.User_Image);


        //Make TimeStamp Visible or Hidden
        holder.Message.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Log.d(TAG,"On Click Text View Message");

                if (isShowing){
                    holder.TimeStamp.setVisibility(View.VISIBLE);
                    Log.d(TAG,"Is Showing Is True");
                    isShowing=false;
                }
                else {
                    holder.TimeStamp.setVisibility(View.GONE);
                    isShowing=true;
                }

            }
        });

    }

}
@Override
public long getItemId(int position) {
    return position;
}

@Override
public int getItemCount() {
    Log.d(TAG,"GET ITEM COUNT--Array Message List Size "+arrayList_message.size());
    return arrayList_message.size();
}

public class ViewHolder extends RecyclerView.ViewHolder {
    TextView Message;
    TextView TimeStamp;

    ImageView User_Image;


    public ViewHolder(View itemView) {
        super(itemView);
        Log.d(TAG,"View Holder Constructor Calling. Now Inflating Layout Items");
        Message = itemView.findViewById(R.id.Single_Item_Chat_Message);
        TimeStamp = itemView.findViewById(R.id.Single_Item_Chat_TimeStamp);
        User_Image = itemView.findViewById(R.id.Single_Item_Chat_ImageView);




    }
}

Whenever i received message as notification after tapping on notification it open same chat screen (Load all previous message first) and when i click on send button to send message it send to other user but not updating my recyclerview. 每当我在点击通知后收到消息作为通知时,它都会打开相同的聊天屏幕(首先加载所有先前的消息),当我单击发送按钮发送消息时,它会发送给其他用户,但不会更新我的recyclerview。

UPDATE : I just found the issue which is fetching earlier messages from local database when i comment chatDatabase() function it works fine. 更新 :我刚刚发现问题,当我注释chatDatabase()函数时,它会从本地数据库中获取较早的消息,它可以正常工作。 but still not able to fix the issue. 但仍然无法解决该问题。

When you are appending a new item to the list in append_chat_conversation method, you are not notifying the adapter about it. 当您将一个新项追加到append_chat_conversation方法中的列表时,您没有在通知适配器。 I don't know how that framework works but you should notify the adapter about any change in the dataset by using the notifyDataSetChaged on the adapter or better using the specific inserted/changed/deleted notify methods for better performance. 我不知道该框架如何工作,但是您应该通过使用适配器上的notifyDataSetChaged或更好地使用特定的插入/更改/删除的notify方法来将数据集中的任何更改通知适配器,以获得更好的性能。

Why don't you call 你为什么不打电话

adapter.notifyDataSetChanged();

after

Chat_Wrapper chat_wrapper = new Chat_Wrapper(Chat_Msg, null, null, null, null, null, null, Chat_TimeStamp, User_Intent, UserImage_Intent, Chat_FROM, null,null,id);
                message.add(chat_wrapper);

as

notifyDataSetChanged only works if you use the add(), insert(), remove(), and clear() on the Adapter. notifyDataSetChanged仅在您在适配器上使用add(),insert(),remove()和clear()时才有效。

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

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