Android Firebase实时数据库聊天应用:消息送达状态背景切换实现
实现Firebase聊天消息发送状态的背景切换
需求说明
用户发送消息时,受网络速度影响可能延迟写入数据库,需要实现:
- 消息未成功发送到数据库时,界面显示深色背景
- 消息成功送达数据库后,自动切换为蓝色背景
具体实现步骤
1. 扩展Messages数据模型
给Messages类新增isSent布尔字段,用来标记消息发送状态,同时支持Firebase的序列化/反序列化:
public class Messages { private String message; private String time; private String date; private String type; private String from; private boolean isSent; // 新增发送状态标记 // Firebase序列化需要空构造函数 public Messages() {} // 带参构造函数,默认未发送 public Messages(String message, String time, String date, String type, String from) { this.message = message; this.time = time; this.date = date; this.type = type; this.from = from; this.isSent = false; } // Getter & Setter public boolean isSent() { return isSent; } public void setSent(boolean sent) { isSent = sent; } // 其他原有字段的Getter/Setter... }
2. 修改SendMessage方法,本地优先展示消息
在ChatActivity的SendMessage方法中,先将未发送状态的消息添加到本地列表并刷新UI,再执行Firebase写入操作:
private void SendMessage() { final String messageText = messageınputtext.getText().toString(); if (TextUtils.isEmpty(messageText)) { return; } // 1. 生成当前时间日期(复用原有逻辑) Calendar calFordDate = Calendar.getInstance(); SimpleDateFormat currentDate = new SimpleDateFormat("dd-MMMM-yyyy"); String saveCurrentDate = currentDate.format(calFordDate.getTime()); Calendar calFordTime = Calendar.getInstance(); SimpleDateFormat currentTime = new SimpleDateFormat("HH:mm aa"); String saveCurrentTime = currentTime.format(calFordTime.getTime()); // 2. 创建本地待发送消息,添加到列表并刷新UI Messages tempMessage = new Messages(messageText, saveCurrentTime, saveCurrentDate, "text", messageSenderID); tempMessage.setSent(false); messagesList.add(tempMessage); messagesAdapter.notifyItemInserted(messagesList.size() - 1); usermessageslist.scrollToPosition(messagesList.size() - 1); messageınputtext.setText(""); // 清空输入框 // 3. 执行Firebase数据库写入 String messagesenderref = "message/" + messageSenderID + "/" + messageReceiverID; String messagereceiverref = "message/" + messageReceiverID + "/" + messageSenderID; DatabaseReference usermessagekeyref = Rootref.child("message") .child(messageSenderID).child(messageReceiverID).push(); final String messagepushid = usermessagekeyref.getKey(); Map<String, Object> messageTextBody = new HashMap<>(); messageTextBody.put("message", messageText); messageTextBody.put("time", saveCurrentTime); messageTextBody.put("date", saveCurrentDate); messageTextBody.put("type", "text"); messageTextBody.put("from", messageSenderID); messageTextBody.put("isSent", true); // 写入数据库时标记为已发送 Map<String, Object> messageBodyDetails = new HashMap<>(); messageBodyDetails.put(messagesenderref + "/" + messagepushid, messageTextBody); messageBodyDetails.put(messagereceiverref + "/" + messagepushid, messageTextBody); Rootref.updateChildren(messageBodyDetails).addOnCompleteListener(task -> { if (task.isSuccessful()) { // 4. 更新本地消息的发送状态,刷新UI int lastIndex = messagesList.size() - 1; Messages sentMessage = messagesList.get(lastIndex); sentMessage.setSent(true); messagesAdapter.notifyItemChanged(lastIndex); } else { String errorMsg = task.getException().getMessage(); Toast.makeText(ChatActivity.this, "发送失败: " + errorMsg, Toast.LENGTH_SHORT).show(); } }); }
3. 修改MessagesAdapter,根据状态切换背景
在MessagesAdapter的onBindViewHolder方法中,根据isSent字段设置不同的背景资源:
@Override public void onBindViewHolder(@NonNull final MessageViewHolder messageViewHolder, final int i) { String messageSenderID = mAuth.getCurrentUser().getUid(); Messages messages = userMessagesList.get(i); String fromUserID = messages.getFrom(); messageViewHolder.ReceiverMessageText.setVisibility(View.INVISIBLE); messageViewHolder.SenderMessageText.setVisibility(View.INVISIBLE); if (fromUserID.equals(messageSenderID)) { messageViewHolder.SenderMessageText.setVisibility(View.VISIBLE); // 根据发送状态切换背景 if (messages.isSent()) { messageViewHolder.SenderMessageText.setBackgroundResource(R.drawable.sendermessage_blue); } else { messageViewHolder.SenderMessageText.setBackgroundResource(R.drawable.sendermessage_dark); } messageViewHolder.SenderMessageText.setTextColor(Color.WHITE); messageViewHolder.SenderMessageText.setText(messages.getMessage()); messageViewHolder.txt_seen.setVisibility(View.VISIBLE); // 原有已读状态逻辑... } else { // 接收方消息原有逻辑不变... } // 日期显示原有逻辑不变... }
4. 创建背景Drawable资源
在res/drawable目录下创建两个背景文件:
sendermessage_dark.xml(未发送状态深色背景)
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <solid android:color="#424242"/> <corners android:radius="16dp"/> <padding android:left="16dp" android:top="8dp" android:right="16dp" android:bottom="8dp"/> </shape>
sendermessage_blue.xml(已发送状态蓝色背景)
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <solid android:color="#2196F3"/> <corners android:radius="16dp"/> <padding android:left="16dp" android:top="8dp" android:right="16dp" android:bottom="8dp"/> </shape>
内容的提问来源于stack exchange,提问作者Muratcan Yıldız
相关产品推荐
相关产品推荐

