我有一个由recyclerview支持的聊天片段。当我手动进入聊天屏幕发送或接收消息时,其工作正常。但当我关闭应用程序并从消息通知中输入应用程序时,它向其他用户发送消息但未更新自己的回收者视图。
聊天片段
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);
}
}
}
聊天适配器
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);
}
}
每当我在点击通知后收到消息作为通知时,它会打开相同的聊天屏幕(先加载所有先前的消息),当我点击发送按钮发送消息时,它会发送给其他用户,但不会更新我的recyclerview。
UPDATE :我发现问题是当我评论chatDatabase()
功能时它从本地数据库获取早期消息它运行正常。但仍无法解决问题。
答案 0 :(得分:1)
当您在append_chat_conversation
方法中向列表追加新项目时,您没有通知适配器。我不知道该框架是如何工作的,但您应该通过使用适配器上的notifyDataSetChaged
或更好地使用特定的插入/更改/删除通知方法来通知适配器有关数据集的任何更改,以获得更好的性能。
答案 1 :(得分:0)
为什么不打电话
adapter.notifyDataSetChanged();
后
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
只有在适配器上使用add(),insert(),remove()和clear()时,notifyDataSetChanged才有效。