package com.lotus_lab.jetchat.ui; import android.util.Log; // Import 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"; // Tag for logging 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, "Messages cleared. Old size: " + oldSize); } public List getMessages() { return new ArrayList<>(this.messages); // Return a copy } public void setMessages(List newMessages) { this.messages.clear(); if (newMessages != null) { // Add null check for safety this.messages.addAll(newMessages); } notifyDataSetChanged(); // Consider using DiffUtil for better performance in production Log.d(ADAPTER_TAG, "Messages set. New count: " + this.messages.size()); } public void addMessage(ChatMessage message) { if (message == null) { Log.w(ADAPTER_TAG, "Attempted to add a null message."); return; } this.messages.add(message); notifyItemInserted(messages.size() - 1); Log.d(ADAPTER_TAG, "Message added. Role: " + (message.role != null ? message.role : "null") + ", Content: '" + (message.content != null ? message.content : "null") + "'. New count: " + messages.size()); } @NonNull @Override public MessageViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { Log.d(ADAPTER_TAG, "onCreateViewHolder called for viewType: " + 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: " + position); if (message == null) { Log.e(ADAPTER_TAG, "Message object is NULL at position " + position + ". Hiding item."); holder.itemView.setVisibility(View.GONE); // Hide the item if message is null return; } // Log the raw role and content from the ChatMessage object Log.d(ADAPTER_TAG, "Raw Message Role: '" + message.role + "'"); Log.d(ADAPTER_TAG, "Raw Message Content: '" + message.content + "'"); if (message.role == null || message.content == null) { holder.itemView.setVisibility(View.GONE); Log.w(ADAPTER_TAG, "Message role or content is null at position " + position + ". Role: '" + message.role + "', Content: '" + message.content + "'. Hiding item."); return; } // Ensure item is visible if data is valid holder.itemView.setVisibility(View.VISIBLE); // Optional: Reset item background if you were setting alternating colors for the whole item in debug // holder.itemView.setBackground(null); // Crucial check: compare role with "assistant" and "user" // Make sure these strings EXACTLY match what's in your ChatMessage.role boolean isAiMessage = "assistant".equals(message.role); // boolean isUserMessage = "user".equals(message.role); // You can also explicitly check for user Log.d(ADAPTER_TAG, "Processed Role: '" + message.role + "', isAiMessage = " + isAiMessage); holder.tvMessage.setText(message.content); holder.tvMessage.setVisibility(View.VISIBLE); // Ensure TextView is visible // Reset text color and background to defaults from XML or a base style, // in case previous debug styles are cached by RecyclerView's ViewHolder. holder.tvMessage.setTextColor(ContextCompat.getColor(holder.itemView.getContext(), android.R.color.black)); // Or your R.color.your_default_text_color // holder.tvMessage.setBackground(null); // Let specific backgrounds below take precedence ConstraintLayout.LayoutParams params = (ConstraintLayout.LayoutParams) holder.tvMessage.getLayoutParams(); if (isAiMessage) { Log.d(ADAPTER_TAG, "Applying AI message style for: '" + 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) ); // Example: Different text color for AI messages if needed // holder.tvMessage.setTextColor(ContextCompat.getColor(holder.itemView.getContext(), R.color.ai_text_color)); } else { // Assuming any non-AI message is a user message for now // If you have other roles like "system", you'll need more specific checks. Log.d(ADAPTER_TAG, "Applying User message style for: '" + message.content.substring(0, Math.min(message.content.length(), 20)) + "...'"); holder.ivAiAvatar.setVisibility(View.GONE); holder.ivUserAvatar.setVisibility(View.GONE); // As per your item_message.xml, user avatar is GONE by default params.horizontalBias = 1.0f; // 用户消息靠右 holder.tvMessage.setBackground( ContextCompat.getDrawable(holder.itemView.getContext(), R.drawable.bg_user_message_bubble) ); // Example: Different text color for user messages if needed // holder.tvMessage.setTextColor(ContextCompat.getColor(holder.itemView.getContext(), R.color.user_text_color)); } holder.tvMessage.setLayoutParams(params); Log.i(ADAPTER_TAG, "Finished applying style for position: " + 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); tvMessage = itemView.findViewById(R.id.tv_message); if (ivAiAvatar == null) Log.e(ADAPTER_TAG, "MessageViewHolder: ivAiAvatar is null!"); if (ivUserAvatar == null) Log.e(ADAPTER_TAG, "MessageViewHolder: ivUserAvatar is null!"); if (tvMessage == null) Log.e(ADAPTER_TAG, "MessageViewHolder: tvMessage is null!"); } } }