JetChat/src/main/java/com/lotus_lab/jetchat/ui/ChatAdapter.java

173 lines
8.3 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.lotus_lab.jetchat.ui;
import android.util.Log; // 导入 Log 类
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.RecyclerView;
import com.lotus_lab.jetchat.R;
import com.lotus_lab.jetchat.data.ChatMessage; // 确保 ChatMessage 类有 role 属性
import java.util.ArrayList;
import java.util.List;
public class ChatAdapter extends RecyclerView.Adapter<ChatAdapter.MessageViewHolder> {
private static final String ADAPTER_TAG = "ChatAdapter"; // 用于日志记录的标签
private final List<ChatMessage> messages;
// 可以在 ChatMessage 类中定义这些常量,或者在这里定义,以避免硬编码字符串 "assistant" 和 "user"
// public static final String ROLE_USER = "user";
// public static final String ROLE_ASSISTANT = "assistant";
public ChatAdapter(List<ChatMessage> initialMessages) {
this.messages = new ArrayList<>(initialMessages);
}
public void clearMessages() {
int oldSize = messages.size();
this.messages.clear();
notifyItemRangeRemoved(0, oldSize);
Log.d(ADAPTER_TAG, "消息已清空。旧数量: " + oldSize);
}
public List<ChatMessage> getMessages() {
return new ArrayList<>(this.messages); // 返回列表的副本
}
public void setMessages(List<ChatMessage> newMessages) {
this.messages.clear();
if (newMessages != null) { // 为安全起见,添加 null 检查
this.messages.addAll(newMessages);
}
notifyDataSetChanged(); // 在生产环境中,考虑使用 DiffUtil 以获得更好的性能
Log.d(ADAPTER_TAG, "消息已设置。新数量: " + this.messages.size());
}
public void addMessage(ChatMessage message) {
if (message == null) {
Log.w(ADAPTER_TAG, "尝试添加一个 null 消息。");
return;
}
this.messages.add(message);
notifyItemInserted(messages.size() - 1);
Log.d(ADAPTER_TAG, "消息已添加。角色: " + (message.role != null ? message.role : "null") +
", 内容: '" + (message.content != null ? message.content.substring(0, Math.min(message.content.length(), 50))+"..." : "null") + // 截断过长的内容日志
"'. 新数量: " + messages.size());
}
@NonNull
@Override
public MessageViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
Log.d(ADAPTER_TAG, "onCreateViewHolder 调用,视图类型: " + viewType);
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_message, parent, false);
return new MessageViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull MessageViewHolder holder, int position) {
ChatMessage message = messages.get(position);
Log.i(ADAPTER_TAG, "-----------------------------------------------------");
Log.i(ADAPTER_TAG, "onBindViewHolder - 位置: " + position);
if (message == null) {
Log.e(ADAPTER_TAG, "位置 " + position + " 的 Message 对象为 NULL。正在隐藏项目。");
holder.itemView.setVisibility(View.GONE); // 如果消息为 null则隐藏该项目
return;
}
// 记录 ChatMessage 对象的原始角色和内容
Log.d(ADAPTER_TAG, "原始消息角色: '" + message.role + "'");
Log.d(ADAPTER_TAG, "原始消息内容: '" + message.content + "'");
if (message.role == null || message.content == null) {
holder.itemView.setVisibility(View.GONE);
Log.w(ADAPTER_TAG, "位置 " + position + " 的消息角色或内容为 null。角色: '" + message.role + "', 内容: '" + message.content + "'. 正在隐藏项目。");
return;
}
// 如果数据有效,确保项目可见
holder.itemView.setVisibility(View.VISIBLE);
// 可选:如果在调试中为整个项目设置了交替颜色,则重置项目背景
// holder.itemView.setBackground(null);
// 关键检查:将角色与 "assistant" 和 "user" 进行比较
// 确保这些字符串与 ChatMessage.role 中的内容完全匹配
boolean isAiMessage = "assistant".equals(message.role);
// boolean isUserMessage = "user".equals(message.role); // 也可以显式检查用户消息
Log.d(ADAPTER_TAG, "处理后的角色: '" + message.role + "', 是否为AI消息 = " + isAiMessage);
// 直接设置文本内容,它已经包含了模型标识(例如 "[模型: xxx]\n实际内容..."
holder.tvMessage.setText(message.content);
holder.tvMessage.setVisibility(View.VISIBLE); // 确保 TextView 可见
// 将文本颜色和背景重置为 XML 或基本样式中的默认值,
// 以防 RecyclerView 的 ViewHolder 缓存了之前的调试样式。
// holder.tvMessage.setTextColor(ContextCompat.getColor(holder.itemView.getContext(), android.R.color.black)); // 或者你的 R.color.your_default_text_color
// holder.tvMessage.setBackground(null); // 让下面的特定背景优先
ConstraintLayout.LayoutParams params = (ConstraintLayout.LayoutParams) holder.tvMessage.getLayoutParams();
if (isAiMessage) {
Log.d(ADAPTER_TAG, "正在为AI消息应用样式: '" + message.content.substring(0, Math.min(message.content.length(), 20)) + "...'");
holder.ivAiAvatar.setVisibility(View.VISIBLE);
holder.ivUserAvatar.setVisibility(View.GONE);
params.horizontalBias = 0.0f; // AI 消息靠左
holder.tvMessage.setBackground(
ContextCompat.getDrawable(holder.itemView.getContext(), R.drawable.bg_reply_message_bubble)
);
// 示例:如果需要,可以为 AI 消息设置不同的文本颜色
// holder.tvMessage.setTextColor(ContextCompat.getColor(holder.itemView.getContext(), R.color.ai_text_color));
} else { // 目前假设任何非 AI 消息都是用户消息
// 如果有其他角色(如 "system"),则需要更具体的检查。
Log.d(ADAPTER_TAG, "正在为用户消息应用样式: '" + message.content.substring(0, Math.min(message.content.length(), 20)) + "...'");
holder.ivAiAvatar.setVisibility(View.GONE);
holder.ivUserAvatar.setVisibility(View.GONE); // 根据你的 item_message.xml用户头像默认为 GONE
params.horizontalBias = 1.0f; // 用户消息靠右
holder.tvMessage.setBackground(
ContextCompat.getDrawable(holder.itemView.getContext(), R.drawable.bg_user_message_bubble)
);
// 示例:如果需要,可以为用户消息设置不同的文本颜色
// holder.tvMessage.setTextColor(ContextCompat.getColor(holder.itemView.getContext(), R.color.user_text_color));
}
holder.tvMessage.setLayoutParams(params);
Log.i(ADAPTER_TAG, "已完成为位置 " + position + " 应用样式");
Log.i(ADAPTER_TAG, "-----------------------------------------------------");
}
@Override
public int getItemCount() {
return messages.size();
}
static class MessageViewHolder extends RecyclerView.ViewHolder {
ImageView ivAiAvatar;
ImageView ivUserAvatar;
TextView tvMessage;
MessageViewHolder(@NonNull View itemView) {
super(itemView);
ivAiAvatar = itemView.findViewById(R.id.iv_ai_avatar);
ivUserAvatar = itemView.findViewById(R.id.iv_user_avatar); // 虽然用户头像默认GONE但ID还是需要的
tvMessage = itemView.findViewById(R.id.tv_message);
if (ivAiAvatar == null) Log.e(ADAPTER_TAG, "MessageViewHolder: ivAiAvatar 为 null!");
// ivUserAvatar 在你的布局中可能确实不存在或ID不同如果它总是GONE可以不查找或处理null
// if (ivUserAvatar == null) Log.e(ADAPTER_TAG, "MessageViewHolder: ivUserAvatar 为 null!");
if (tvMessage == null) Log.e(ADAPTER_TAG, "MessageViewHolder: tvMessage 为 null!");
}
}
}