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

182 lines
7.7 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 androidx.annotation.NonNull;
import androidx.core.content.FileProvider;
import androidx.recyclerview.widget.DiffUtil;
import androidx.recyclerview.widget.ListAdapter;
import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import com.example.livestreaming.databinding.ItemConversationBinding;
public class ConversationsAdapter extends ListAdapter<ConversationItem, ConversationsAdapter.VH> {
public interface OnConversationClickListener {
void onConversationClick(ConversationItem item);
}
private final OnConversationClickListener onConversationClickListener;
public ConversationsAdapter(OnConversationClickListener onConversationClickListener) {
super(DIFF);
this.onConversationClickListener = onConversationClickListener;
}
@NonNull
@Override
public VH onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
ItemConversationBinding binding = ItemConversationBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
return new VH(binding, onConversationClickListener);
}
@Override
public void onBindViewHolder(@NonNull VH holder, int position) {
holder.bind(getItem(position));
}
static class VH extends RecyclerView.ViewHolder {
private final ItemConversationBinding binding;
private final OnConversationClickListener onConversationClickListener;
VH(ItemConversationBinding binding, OnConversationClickListener onConversationClickListener) {
super(binding.getRoot());
this.binding = binding;
this.onConversationClickListener = onConversationClickListener;
}
void bind(ConversationItem item) {
binding.title.setText(item != null && item.getTitle() != null ? item.getTitle() : "");
binding.lastMessage.setText(item != null && item.getLastMessage() != null ? item.getLastMessage() : "");
binding.timeText.setText(item != null && item.getTimeText() != null ? item.getTimeText() : "");
int unread = item != null ? item.getUnreadCount() : 0;
if (unread > 0) {
binding.unreadBadge.setVisibility(View.VISIBLE);
binding.unreadBadge.setText(unread > 99 ? "99+" : String.valueOf(unread));
} else {
binding.unreadBadge.setVisibility(View.GONE);
}
// 加载头像
loadAvatar(item);
binding.getRoot().setOnClickListener(v -> {
if (item == null) return;
if (onConversationClickListener != null) onConversationClickListener.onConversationClick(item);
});
}
private void loadAvatar(ConversationItem item) {
// TODO: 接入后端接口 - 加载会话对方头像
// 接口路径: GET /api/users/{userId}/avatar 或直接从ConversationItem的avatarUrl字段获取
// 如果ConversationItem对象包含avatarUrl字段直接使用该URL加载头像
// 如果没有avatarUrl需要根据会话类型私信/群聊)调用相应接口获取头像
if (binding.avatar == null) return;
// 设置圆形裁剪
setupAvatarOutline();
try {
// 优先使用ConversationItem中的avatarUrl从后端获取
// 尝试从 SharedPreferences 加载用户头像
String avatarUri = binding.avatar.getContext()
.getSharedPreferences("profile_prefs", android.content.Context.MODE_PRIVATE)
.getString("profile_avatar_uri", null);
if (!TextUtils.isEmpty(avatarUri)) {
// 尝试解析 URI
Uri uri = Uri.parse(avatarUri);
// 如果是 file:// 协议,尝试转换为 FileProvider URI
if ("file".equals(uri.getScheme())) {
try {
java.io.File file = new java.io.File(uri.getPath());
if (file.exists()) {
uri = FileProvider.getUriForFile(
binding.avatar.getContext(),
binding.avatar.getContext().getPackageName() + ".fileprovider",
file
);
}
} catch (Exception e) {
// 如果转换失败,使用原始 URI
}
}
Glide.with(binding.avatar)
.load(uri)
.circleCrop()
.error(R.drawable.ic_account_circle_24)
.placeholder(R.drawable.ic_account_circle_24)
.into(binding.avatar);
return;
}
int avatarRes = binding.avatar.getContext()
.getSharedPreferences("profile_prefs", android.content.Context.MODE_PRIVATE)
.getInt("profile_avatar_res", 0);
if (avatarRes != 0) {
Glide.with(binding.avatar)
.load(avatarRes)
.circleCrop()
.error(R.drawable.ic_account_circle_24)
.placeholder(R.drawable.ic_account_circle_24)
.into(binding.avatar);
return;
}
// 如果没有保存的头像,使用默认头像
Glide.with(binding.avatar)
.load(R.drawable.ic_account_circle_24)
.circleCrop()
.into(binding.avatar);
} catch (Exception e) {
// 如果加载失败,使用默认头像
Glide.with(binding.avatar)
.load(R.drawable.ic_account_circle_24)
.circleCrop()
.into(binding.avatar);
}
}
private void setupAvatarOutline() {
if (binding.avatar == null) return;
// 设置圆形裁剪,确保在模拟器上也能正常工作
binding.avatar.post(() -> {
if (binding.avatar.getWidth() > 0 && binding.avatar.getHeight() > 0) {
binding.avatar.setOutlineProvider(new ViewOutlineProvider() {
@Override
public void getOutline(View view, Outline outline) {
outline.setOval(0, 0, view.getWidth(), view.getHeight());
}
});
binding.avatar.setClipToOutline(true);
}
});
}
}
private static final DiffUtil.ItemCallback<ConversationItem> DIFF = new DiffUtil.ItemCallback<ConversationItem>() {
@Override
public boolean areItemsTheSame(@NonNull ConversationItem oldItem, @NonNull ConversationItem newItem) {
String o = oldItem.getId();
String n = newItem.getId();
return o != null && o.equals(n);
}
@Override
public boolean areContentsTheSame(@NonNull ConversationItem oldItem, @NonNull ConversationItem newItem) {
return oldItem.equals(newItem);
}
};
}