我正在应用程序中创建聊天区域,但是我面临的唯一问题是,每当我输入一条新消息时,都会在“回收者”视图中删除以前显示的某些消息。但是这些消息存在于“ firestore”中。它们不会从那里被删除,但是一旦我输入新消息,它们就会从回收者视图中消失。当我重新启动活动时,所有消息都完美存在。.但是仅当我输入新消息时,以及在“ recyclerview”中滚动时,才会出现问题。这是代码...
这是chatModel
类:
import java.io.Serializable;
import java.util.Date;
public class chatModel implements Serializable {
private String Message,sender,Type,id;
private Date Time;
public chatModel()
{
}
public chatModel(String Message, String sender, String type,Date Time ,String id) {
this.Message = Message;
this.sender = sender;
Type = type;
this.Time = Time;
this.id = id;
}
public String getMessage() {
return Message;
}
public void setMessage(String message) {
Message = message;
}
public String getSender() {
return sender;
}
public void setSender(String sender) {
this.sender = sender;
}
public String getType() {
return Type;
}
public void setType(String type) {
Type = type;
}
public Date getTime() {
return Time;
}
public void setTime(Date time) {
Time = time;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
这是DiscussionActivity
类:
public class DiscussionActivity extends AppCompatActivity {
private FirebaseAuth mAuth;
private FirebaseFirestore mFirestore;
private FirebaseStorage mStorage;
private DatabaseReference mDatabase;
private EditText msg;
private Button sendBtn;
private ImageView addDocs;
private Uri imageUri;
private String url;
private RecyclerView mChatContainer;
private List<chatModel> chatList;
private chatAdapter adapter;
private int position=0;
String getMessage,getTitle,getDate;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_discussion);
mAuth = FirebaseAuth.getInstance();
mFirestore = FirebaseFirestore.getInstance();
mStorage = FirebaseStorage.getInstance();
mDatabase = FirebaseDatabase.getInstance().getReference();
msg = (EditText)findViewById(R.id.textContent);
sendBtn = (Button)findViewById(R.id.sendMsg);
addDocs = (ImageView)findViewById(R.id.include_documents);
getTitle = getIntent().getExtras().getString("Title");
int getCurrentYear = Calendar.getInstance().get(Calendar.YEAR);
int getCurrentMonth = Calendar.getInstance().get(Calendar.MONTH);
int getCurrentDate = Calendar.getInstance().get(Calendar.DATE);
getDate=getCurrentDate+getCurrentMonth+getCurrentYear+"";
mChatContainer = (RecyclerView)findViewById(R.id.chatContainer);
chatList = new ArrayList<>();
sendBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String message = msg.getText().toString().trim();
int random = new Random().nextInt();
Map chat = new HashMap();
chat.put("Message",message);
chat.put("sender",mAuth.getCurrentUser().getUid());
chat.put("Time",FieldValue.serverTimestamp());
chat.put("Type","text");
chat.put("id",String.valueOf(random));
mFirestore.collection("Ideas").document(getTitle).collection("Discussions").add(chat).addOnCompleteListener(DiscussionActivity.this, new OnCompleteListener() {
@Override
public void onComplete(@NonNull Task task) {
if(task.isSuccessful())
{
msg.setText("");
}
}
});
}
});
addDocs.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
discussionOptionsSheetDialog obj = new discussionOptionsSheetDialog();
Bundle bundle = new Bundle();
bundle.putString("Title",getTitle);
bundle.putString("id",mAuth.getCurrentUser().getUid());
obj.setArguments(bundle);
obj.show(getSupportFragmentManager(),"discussionOptionsBottomSheet");
}
});
adapter = new chatAdapter(chatList,getTitle);
Query first = mFirestore.collection("Ideas").document(getTitle).collection("Discussions").orderBy("Time");
first.addSnapshotListener(DiscussionActivity.this, new EventListener<QuerySnapshot>() {
@Override
public void onEvent(QuerySnapshot documentSnapshots, FirebaseFirestoreException e) {
if(!documentSnapshots.isEmpty())
{
for(DocumentChange doc:documentSnapshots.getDocumentChanges())
{
if(doc.getType()==DocumentChange.Type.ADDED)
{
chatModel obj = doc.getDocument().toObject(chatModel.class);
chatList.add(obj);
DocumentSnapshot lastVisible = documentSnapshots.getDocuments()
.get(documentSnapshots.size() -1);
Query next = mFirestore.collection("Ideas").document(getTitle).collection("Discussions")
.orderBy("Time").startAfter(lastVisible);
adapter.notifyDataSetChanged();
}
if(doc.getType()==DocumentChange.Type.MODIFIED)
{
String docID = doc.getDocument().getId();
chatModel obj = doc.getDocument().toObject(chatModel.class);
if(doc.getOldIndex() == doc.getNewIndex())
{
chatList.set(doc.getOldIndex(),obj);
}
else
{
chatList.remove(doc.getOldIndex());
chatList.add(doc.getNewIndex(),obj);
adapter.notifyItemMoved(doc.getOldIndex(),doc.getNewIndex());
}
adapter.notifyDataSetChanged();
}
}
}
}
});
LinearLayoutManager layoutManager = new LinearLayoutManager(DiscussionActivity.this);
layoutManager.setReverseLayout(false);
layoutManager.setStackFromEnd(false);
mChatContainer.setHasFixedSize(false);
mChatContainer.setLayoutManager(layoutManager);
mChatContainer.setAdapter(adapter);
}
}
这是 activity_discussion.xml 文件:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".DiscussionActivity"
android:background="#6D7993">
<android.support.v7.widget.RecyclerView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_above="@id/writingSection"
android:id="@+id/chatContainer"
android:layout_marginRight="5dp">
</android.support.v7.widget.RecyclerView>
<RelativeLayout
android:id="@+id/writingSection"
android:layout_width="379dp"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:background="@drawable/chat_background">
<EditText
android:id="@+id/textContent"
android:layout_width="342dp"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_marginLeft="0dp"
android:layout_toLeftOf="@id/include_documents"
android:hint="Write here.." />
<ImageView
android:layout_width="wrap_content"
android:layout_height="28dp"
android:src="@drawable/include_docs"
android:id="@+id/include_documents"
android:layout_toLeftOf="@id/sendMsg"
android:layout_marginTop="9dp"
android:layout_marginRight="3dp"/>
<Button
android:id="@+id/sendMsg"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_alignParentRight="true"
android:layout_marginRight="2dp"
android:layout_marginTop="7dp"
android:background="@drawable/send_message" />
</RelativeLayout>
这是chatAdapter类:
public class chatAdapter extends
RecyclerView.Adapter<chatAdapter.ViewHolder> {
private FirebaseAuth mAuth;
private FirebaseFirestore mFirestore;
private Context context;
private List<chatModel> chatMsgs;
private String title;
public chatAdapter(List<chatModel> chatMsgs,String title) {
this.chatMsgs = chatMsgs;
this.title = title;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int
viewType) {
mAuth = FirebaseAuth.getInstance();
mFirestore = FirebaseFirestore.getInstance();
context = parent.getContext();
View view =
LayoutInflater.from(context).inflate(R.layout.chat_box_layout,null);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull final ViewHolder holder, final
int position) {
String getSenderId = chatMsgs.get(position).getSender();
final String getSenderMessage =
chatMsgs.get(position).getMessage();
final String getID = chatMsgs.get(position).getId();
final String theType = chatMsgs.get(position).getType();
if(theType.equals("text"))
{
if(getSenderId.equals(mAuth.getCurrentUser().getUid()))
{
holder.aBox.setVisibility(View.GONE);
holder.oIbox.setVisibility(View.GONE);
holder.mIbox.setVisibility(View.GONE);
//To get name...
mFirestore.collection("Users").document(getSenderId).get()
.addOnCompleteListener((Activity) context, new
OnCompleteListener<DocumentSnapshot>() {
@Override
public void onComplete(@NonNull
Task<DocumentSnapshot> task) {
if(task.isSuccessful())
{
String getFirstName =
task.getResult().getString("Firstname");
String getLastName =
task.getResult().getString("Lastname");
holder.mName.setText(getFirstName.charAt(0)+getFirstName.substring(1).toLo . werCase());
}
}
});
holder.mContent.setText(getSenderMessage);
}
if(!getSenderId.equals(mAuth.getCurrentUser().getUid())) {
holder.mBox.setVisibility(View.GONE);
holder.aEdit.setVisibility(View.GONE);
holder.aDelete.setVisibility(View.GONE);
holder.oIbox.setVisibility(View.GONE);
holder.mIbox.setVisibility(View.GONE);
//To get name...
mFirestore.collection("Users").document(getSenderId).get()
.addOnCompleteListener((Activity) context, new OnCompleteListener<DocumentSnapshot>() {
@Override
public void onComplete(@NonNull Task<DocumentSnapshot> task) {
if (task.isSuccessful()) {
String getFirstName = task.getResult().getString("Firstname");
String getLastName = task.getResult().getString("Lastname");
holder.aName.setText(getFirstName.charAt(0) + getFirstName.substring(1).toLowerCase());
}
}
});
holder.aContent.setText(getSenderMessage);
}
}
}
@Override
public int getItemCount() {
return chatMsgs.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
//Variables for my chat lists...
private TextView mName,mContent;
private ImageView mDelete,mEdit;
private RelativeLayout mBox;
//Variable for other person's chat lists....
private TextView aName,aContent;
private ImageView aDelete,aEdit;
private RelativeLayout aBox;
//Variables for my images list..
private RelativeLayout mIbox;
private ImageView myImage,mIDelete;
private TextView myNameInImage;
//Variables for others image list..
private RelativeLayout oIbox;
private ImageView othersImage,oIDelete;
private TextView othersNameInImage;
public ViewHolder(View itemView) {
super(itemView);
//My variable initialization
mName = (TextView)itemView.findViewById(R.id.name);
mContent = (TextView)itemView.findViewById(R.id.chatContent);
mDelete = (ImageView)itemView.findViewById(R.id.delete);
mEdit = (ImageView)itemView.findViewById(R.id.editContent);
mBox = (RelativeLayout)itemView.findViewById(R.id.userChatBox);
//Other people's variables initialization..
aName = (TextView)itemView.findViewById(R.id.othersName);
aContent = (TextView)itemView.findViewById(R.id.othersChatContent);
aDelete = (ImageView)itemView.findViewById(R.id.othersDelete);
aEdit = (ImageView)itemView.findViewById(R.id.othersEditContent);
aBox = (RelativeLayout)itemView.findViewById(R.id.othersChatBox);
}
}
答案 0 :(得分:0)
通过
但是我面临的唯一问题是,每当我输入新消息时...
我假设您的意思是单击sendBtn
时收到消息。考虑到您的代码,提取消息仅在OnCreate()
升高(应用程序启动时)时发生>>因此,它仅发生一次!
您需要做的是将first.addSnapshotListener()
放在一个单独的空格中,并同时调用OnCreate()
和sendBtn.setOnClickListener()
。
我希望我很清楚,并且祝你好运!
答案 1 :(得分:0)
很明显,我更改了单个聊天框项目的布局,就像我试图将当前用户chatbox(我的消息)和另一个用户chatbox设置为相同布局,并尝试相应地隐藏它...那就是我做了两个单独的布局: 1. my_chatbox-显示我的消息 2. other_chatbox.xml-供其他人发送消息。
并相应地更改了我的适配器。...
它现在可以使用,甚至适用于图像。 :)
以下是代码:-
my_chatbox.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<RelativeLayout
android:id="@+id/userChatBox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_marginBottom="5dp"
android:layout_marginTop="5dp"
android:layout_alignParentTop="true">
<RelativeLayout
android:id="@+id/chatBox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:layout_marginLeft="5dp"
android:background="@drawable/chat_background">
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginRight="20dp"
android:text="Name"
android:textAppearance="@style/Base.TextAppearance.AppCompat.Medium"
android:textColor="#000000"
android:textStyle="bold" />
<TextView
android:id="@+id/chatContent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/name"
android:layout_marginBottom="10dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="20dp"
android:text="Content"
android:textAppearance="@style/Base.TextAppearance.AppCompat.Medium"
android:textColor="#000000" />
</RelativeLayout>
<ImageView
android:id="@+id/delete"
android:layout_width="25dp"
android:layout_height="15dp"
android:layout_alignEnd="@+id/chatBox"
android:layout_below="@+id/chatBox"
android:layout_marginTop="-10dp"
android:src="@drawable/delete" />
<ImageView
android:id="@+id/editContent"
android:layout_width="25dp"
android:layout_height="15dp"
android:layout_below="@+id/chatBox"
android:layout_marginTop="-10dp"
android:layout_toStartOf="@+id/delete"
android:src="@drawable/edit"
android:textAppearance="@style/Base.TextAppearance.AppCompat.Small"
/>
</RelativeLayout>
</RelativeLayout>
other_user_chatbox.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/userChatBox"
android:layout_alignParentRight="true"
android:layout_marginRight="10dp"
android:layout_marginBottom="5dp"
android:layout_marginTop="5dp">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/chatBox"
android:layout_marginLeft="5dp"
android:layout_marginBottom="10dp"
android:background="@drawable/chat_background"
android:backgroundTint="#F4DDBB">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/name"
android:text="Name"
android:textColor="#000000"
android:textAppearance="@style/Base.TextAppearance.AppCompat.Medium"
android:textStyle="bold"
android:layout_marginLeft="10dp"
android:layout_marginRight="20dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/name"
android:textAppearance="@style/Base.TextAppearance.AppCompat.Medium"
android:id="@+id/chatContent"
android:text="Content"
android:textColor="#000000"
android:layout_marginLeft="10dp"
android:layout_marginRight="20dp"
android:layout_marginBottom="10dp"/>
</RelativeLayout>
<ImageView
android:id="@+id/othersDelete"
android:layout_width="25dp"
android:layout_height="15dp"
android:layout_below="@id/chatBox"
android:src="@drawable/delete" />
<ImageView
android:layout_width="25dp"
android:layout_height="15dp"
android:textAppearance="@style/Base.TextAppearance.AppCompat.Small"
android:layout_below="@id/chatBox"
android:layout_toRightOf="@id/othersDelete"
android:src="@drawable/edit"
android:layout_marginRight="3dp"
android:id="@+id/othersEditContent"/>
</RelativeLayout>
</RelativeLayout>
只需尝试在两个xml中保持ID相同,以使您的viewHolder不太复杂。
这是我的chatAdapter.class:
public class chatAdapter extends RecyclerView.Adapter<chatAdapter.ViewHolder> {
private FirebaseAuth mAuth;
private FirebaseFirestore mFirestore;
private Context context;
private static final int SENT = 0;
private static final int RECEIVED = 1;
private String userID;
private List<chatModel> chatMsgs;
private String title;
public chatAdapter(List<chatModel> chatMsgs,String title,String userID) {
this.chatMsgs = chatMsgs;
this.title = title;
this.userID = userID;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
mAuth = FirebaseAuth.getInstance();
mFirestore = FirebaseFirestore.getInstance();
context = parent.getContext();
View view = null;
if(viewType == SENT)
{
view =
LayoutInflater.from(context).inflate(R.layout.chat_box_layout,parent,false);
}
if(viewType == RECEIVED)
{
view =
LayoutInflater.from(context).inflate(R.layout.other_user_chat_box,parent,false);
}
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull final ViewHolder holder, final int position) {
String getSenderId = chatMsgs.get(position).getSender();
final String getSenderMessage = chatMsgs.get(position).getMessage();
final String getID = chatMsgs.get(position).getId();
final String theType = chatMsgs.get(position).getType();
if(theType.equals("text"))
{
//To get name...
mFirestore.collection("Users").document(getSenderId).get()
.addOnCompleteListener((Activity) context, new OnCompleteListener<DocumentSnapshot>() {
@Override
public void onComplete(@NonNull Task<DocumentSnapshot> task) {
if (task.isSuccessful()) {
String getFirstName = task.getResult().getString("Firstname");
String getLastName = task.getResult().getString("Lastname");
holder.mName.setText(getFirstName.charAt(0) + getFirstName.substring(1).toLowerCase());
}
}
});
holder.mContent.setText(getSenderMessage);
}
}
@Override
public int getItemCount() {
return chatMsgs.size();
}
@Override
public int getItemViewType(int position) {
if (chatMsgs.get(position).getSender() . equals(userID))
return SENT;
else
return RECEIVED;
}
public class ViewHolder extends RecyclerView.ViewHolder{
//Variables for my chat lists...
private TextView mName,mContent;
private ImageView mDelete,mEdit;
private RelativeLayout mBox;
public ViewHolder(View itemView) {
super(itemView);
//variable initialization
mName = (TextView)itemView.findViewById(R.id.name);
mContent = (TextView)itemView.findViewById(R.id.chatContent);
mDelete = (ImageView)itemView.findViewById(R.id.delete);
mEdit = (ImageView)itemView.findViewById(R.id.editContent);
mBox = (RelativeLayout)itemView.findViewById(R.id.userChatBox);
}
}
}
希望它可以帮助遇到相同问题的任何其他人,如果有兴趣,也可以帮助其他人。.:)