package com.example.livestreaming; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.LinearLayout; 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 com.example.livestreaming.net.Room; public class WaterfallRoomsAdapter extends ListAdapter { public interface OnRoomClickListener { void onRoomClick(Room room); } private final OnRoomClickListener onRoomClick; public WaterfallRoomsAdapter(OnRoomClickListener onRoomClick) { super(DIFF); this.onRoomClick = onRoomClick; } @NonNull @Override public RoomVH onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()) .inflate(R.layout.item_room_waterfall, parent, false); return new RoomVH(view, onRoomClick); } @Override public void onBindViewHolder(@NonNull RoomVH holder, int position) { holder.bind(getItem(position)); } static class RoomVH extends RecyclerView.ViewHolder { private final ImageView coverImage; private final TextView liveBadge; private final LinearLayout viewerCountLayout; private final TextView viewerCount; private final TextView roomTitle; private final ImageView streamerAvatar; private final TextView streamerName; private final TextView hotBadge; private final OnRoomClickListener onRoomClick; RoomVH(View itemView, OnRoomClickListener onRoomClick) { super(itemView); this.onRoomClick = onRoomClick; coverImage = itemView.findViewById(R.id.coverImage); liveBadge = itemView.findViewById(R.id.liveBadge); viewerCountLayout = itemView.findViewById(R.id.viewerCountLayout); viewerCount = itemView.findViewById(R.id.viewerCount); roomTitle = itemView.findViewById(R.id.roomTitle); streamerAvatar = itemView.findViewById(R.id.streamerAvatar); streamerName = itemView.findViewById(R.id.streamerName); hotBadge = itemView.findViewById(R.id.hotBadge); } void bind(Room room) { // TODO: 接入后端接口 - 从后端获取房间封面图片URL // 接口路径: GET /api/rooms/{roomId}/cover // 请求参数: roomId (路径参数) // 返回数据格式: ApiResponse<{coverUrl: string}> // 或者Room对象应包含coverUrl字段,直接从room.getCoverUrl()获取 // TODO: 接入后端接口 - 从后端获取主播头像URL // 接口路径: GET /api/user/profile/{streamerId} // 请求参数: streamerId (路径参数,从Room对象中获取streamerId) // 返回数据格式: ApiResponse<{avatarUrl: string}> // TODO: 接入后端接口 - 获取房间观看人数 // 接口路径: GET /api/rooms/{roomId}/viewers/count // 请求参数: roomId (路径参数) // 返回数据格式: ApiResponse<{viewerCount: number}> // 或者Room对象应包含viewerCount字段,直接从room.getViewerCount()获取 if (room == null) return; // 设置标题 roomTitle.setText(room.getTitle() != null ? room.getTitle() : "(无标题)"); // 设置主播名称 streamerName.setText(room.getStreamerName() != null ? room.getStreamerName() : ""); // 加载封面图片 String seed = room.getId() != null ? room.getId() : String.valueOf(getBindingAdapterPosition()); int h = Math.abs(seed.hashCode()); int imgIndex = (h % 10); String[] colors = {"ff6b6b", "4ecdc4", "45b7d1", "96ceb4", "ffeaa7", "dfe6e9", "fd79a8", "a29bfe", "00b894", "e17055"}; String color = colors[imgIndex]; String imageUrl = "https://placehold.co/600x450/" + color + "/ffffff?text=LIVE"; Glide.with(coverImage) .load(imageUrl) .placeholder(R.drawable.bg_cover_placeholder) .centerCrop() .into(coverImage); // 设置直播状态 if (room.isLive()) { liveBadge.setVisibility(View.VISIBLE); viewerCountLayout.setVisibility(View.VISIBLE); int viewers = getViewerCount(room); viewerCount.setText(String.valueOf(viewers)); // 如果观看人数超过100,显示热门标签 if (viewers > 100) { hotBadge.setVisibility(View.VISIBLE); } else { hotBadge.setVisibility(View.GONE); } } else { liveBadge.setVisibility(View.GONE); viewerCountLayout.setVisibility(View.GONE); hotBadge.setVisibility(View.GONE); } // 点击事件 itemView.setOnClickListener(v -> { if (onRoomClick != null) { onRoomClick.onRoomClick(room); } }); } private int getViewerCount(Room room) { try { String seed = room.getId() != null ? room.getId() : String.valueOf(getBindingAdapterPosition()); int h = Math.abs(seed.hashCode()); return (h % 380) + 5; } catch (Exception ignored) { return 0; } } } private static final DiffUtil.ItemCallback DIFF = new DiffUtil.ItemCallback() { @Override public boolean areItemsTheSame(@NonNull Room oldItem, @NonNull Room newItem) { String o = oldItem.getId(); String n = newItem.getId(); return o != null && o.equals(n); } @Override public boolean areContentsTheSame(@NonNull Room oldItem, @NonNull Room newItem) { return oldItem.equals(newItem); } }; }