zhibo/android-app/app/src/main/java/com/example/livestreaming/ConversationMessagesAdapter.java

225 lines
8.7 KiB
Java
Raw Normal View History

2025-12-19 15:11:49 +08:00
package com.example.livestreaming;
import android.graphics.Outline;
import android.net.Uri;
import android.text.TextUtils;
2025-12-19 15:11:49 +08:00
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewOutlineProvider;
import android.widget.ImageView;
2025-12-19 15:11:49 +08:00
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;
2025-12-19 15:11:49 +08:00
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
public class ConversationMessagesAdapter extends ListAdapter<ChatMessage, RecyclerView.ViewHolder> {
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;
2025-12-19 15:11:49 +08:00
private final TextView nameText;
private final TextView msgText;
private final TextView timeText;
IncomingVH(@NonNull View itemView) {
super(itemView);
avatarView = itemView.findViewById(R.id.avatarView);
2025-12-19 15:11:49 +08:00
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);
}
});
2025-12-19 15:11:49 +08:00
}
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);
}
2025-12-19 15:11:49 +08:00
}
}
static class OutgoingVH extends RecyclerView.ViewHolder {
private final ImageView avatarView;
2025-12-19 15:11:49 +08:00
private final TextView msgText;
private final TextView timeText;
OutgoingVH(@NonNull View itemView) {
super(itemView);
avatarView = itemView.findViewById(R.id.avatarView);
2025-12-19 15:11:49 +08:00
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);
}
});
2025-12-19 15:11:49 +08:00
}
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);
}
2025-12-19 15:11:49 +08:00
}
}
private static final DiffUtil.ItemCallback<ChatMessage> DIFF = new DiffUtil.ItemCallback<ChatMessage>() {
@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();
}
};
}