package com.example.livestreaming; import android.graphics.Outline; import android.net.Uri; import android.text.TextUtils; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.ViewOutlineProvider; import android.widget.ImageView; import android.widget.TextView; import androidx.annotation.NonNull; import androidx.recyclerview.widget.DiffUtil; import androidx.recyclerview.widget.ListAdapter; import androidx.recyclerview.widget.RecyclerView; import com.bumptech.glide.Glide; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Locale; public class ConversationMessagesAdapter extends ListAdapter { private static final int TYPE_INCOMING = 1; private static final int TYPE_OUTGOING = 2; private static final SimpleDateFormat TIME_FORMAT = new SimpleDateFormat("HH:mm", Locale.getDefault()); public ConversationMessagesAdapter() { super(DIFF); } @Override public int getItemViewType(int position) { ChatMessage msg = getItem(position); if (msg == null) return TYPE_INCOMING; String u = msg.getUsername(); return "我".equals(u) ? TYPE_OUTGOING : TYPE_INCOMING; } @NonNull @Override public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { LayoutInflater inflater = LayoutInflater.from(parent.getContext()); if (viewType == TYPE_OUTGOING) { View v = inflater.inflate(R.layout.item_conversation_message_outgoing, parent, false); return new OutgoingVH(v); } View v = inflater.inflate(R.layout.item_conversation_message_incoming, parent, false); return new IncomingVH(v); } @Override public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { ChatMessage msg = getItem(position); if (holder instanceof IncomingVH) { ((IncomingVH) holder).bind(msg); } else if (holder instanceof OutgoingVH) { ((OutgoingVH) holder).bind(msg); } } static class IncomingVH extends RecyclerView.ViewHolder { private final ImageView avatarView; private final TextView nameText; private final TextView msgText; private final TextView timeText; IncomingVH(@NonNull View itemView) { super(itemView); avatarView = itemView.findViewById(R.id.avatarView); nameText = itemView.findViewById(R.id.nameText); msgText = itemView.findViewById(R.id.messageText); timeText = itemView.findViewById(R.id.timeText); setupAvatarOutline(); } private void setupAvatarOutline() { if (avatarView == null) return; // 设置圆形裁剪,确保在模拟器上也能正常工作 // 使用post确保在View布局完成后再设置outline avatarView.post(() -> { if (avatarView.getWidth() > 0 && avatarView.getHeight() > 0) { avatarView.setOutlineProvider(new ViewOutlineProvider() { @Override public void getOutline(View view, Outline outline) { outline.setOval(0, 0, view.getWidth(), view.getHeight()); } }); avatarView.setClipToOutline(true); } }); } void bind(ChatMessage message) { if (message == null) return; nameText.setText(message.getUsername() != null ? message.getUsername() : ""); msgText.setText(message.getMessage() != null ? message.getMessage() : ""); timeText.setText(TIME_FORMAT.format(new Date(message.getTimestamp()))); // 确保头像圆形裁剪设置正确 setupAvatarOutline(); // 加载对方头像(可以根据用户名或其他信息加载) loadAvatar(message.getUsername()); } private void loadAvatar(String username) { if (avatarView == null) return; // 这里可以根据用户名加载对应的头像 // 暂时使用默认头像,后续可以根据实际需求从服务器或本地加载 try { // 可以根据username从SharedPreferences或其他地方加载头像 // 这里先使用默认头像,使用Glide确保圆形裁剪 Glide.with(avatarView) .load(R.drawable.ic_account_circle_24) .circleCrop() .into(avatarView); } catch (Exception e) { Glide.with(avatarView) .load(R.drawable.ic_account_circle_24) .circleCrop() .into(avatarView); } } } static class OutgoingVH extends RecyclerView.ViewHolder { private final ImageView avatarView; private final TextView msgText; private final TextView timeText; OutgoingVH(@NonNull View itemView) { super(itemView); avatarView = itemView.findViewById(R.id.avatarView); msgText = itemView.findViewById(R.id.messageText); timeText = itemView.findViewById(R.id.timeText); setupAvatarOutline(); } private void setupAvatarOutline() { if (avatarView == null) return; // 设置圆形裁剪,确保在模拟器上也能正常工作 // 使用post确保在View布局完成后再设置outline avatarView.post(() -> { if (avatarView.getWidth() > 0 && avatarView.getHeight() > 0) { avatarView.setOutlineProvider(new ViewOutlineProvider() { @Override public void getOutline(View view, Outline outline) { outline.setOval(0, 0, view.getWidth(), view.getHeight()); } }); avatarView.setClipToOutline(true); } }); } void bind(ChatMessage message) { if (message == null) return; msgText.setText(message.getMessage() != null ? message.getMessage() : ""); timeText.setText(TIME_FORMAT.format(new Date(message.getTimestamp()))); // 确保头像圆形裁剪设置正确 setupAvatarOutline(); // 加载用户头像 loadAvatar(); } private void loadAvatar() { if (avatarView == null) return; try { String avatarUri = avatarView.getContext() .getSharedPreferences("profile_prefs", android.content.Context.MODE_PRIVATE) .getString("profile_avatar_uri", null); if (!TextUtils.isEmpty(avatarUri)) { Glide.with(avatarView) .load(Uri.parse(avatarUri)) .circleCrop() .error(R.drawable.ic_account_circle_24) .into(avatarView); return; } int avatarRes = avatarView.getContext() .getSharedPreferences("profile_prefs", android.content.Context.MODE_PRIVATE) .getInt("profile_avatar_res", 0); if (avatarRes != 0) { Glide.with(avatarView) .load(avatarRes) .circleCrop() .error(R.drawable.ic_account_circle_24) .into(avatarView); } else { Glide.with(avatarView) .load(R.drawable.ic_account_circle_24) .circleCrop() .into(avatarView); } } catch (Exception e) { Glide.with(avatarView) .load(R.drawable.ic_account_circle_24) .circleCrop() .into(avatarView); } } } private static final DiffUtil.ItemCallback DIFF = new DiffUtil.ItemCallback() { @Override public boolean areItemsTheSame(@NonNull ChatMessage oldItem, @NonNull ChatMessage newItem) { return oldItem.getTimestamp() == newItem.getTimestamp(); } @Override public boolean areContentsTheSame(@NonNull ChatMessage oldItem, @NonNull ChatMessage newItem) { return oldItem.getTimestamp() == newItem.getTimestamp(); } }; }