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 { private static final String ADAPTER_TAG = "ChatAdapter"; // 用于日志记录的标签 private final List messages; // 可以在 ChatMessage 类中定义这些常量,或者在这里定义,以避免硬编码字符串 "assistant" 和 "user" // public static final String ROLE_USER = "user"; // public static final String ROLE_ASSISTANT = "assistant"; public ChatAdapter(List 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 getMessages() { return new ArrayList<>(this.messages); // 返回列表的副本 } public void setMessages(List 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!"); } } }