173 lines
8.3 KiB
Java
173 lines
8.3 KiB
Java
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!");
|
||
}
|
||
}
|
||
} |