From b3726557e561952ca5a474dcb61a43d14b8f375a Mon Sep 17 00:00:00 2001 From: xiao12feng8 <16507319+xiao12feng8@user.noreply.gitee.com> Date: Tue, 30 Dec 2025 19:20:52 +0800 Subject: [PATCH] =?UTF-8?q?question=EF=BC=9A=E6=9C=AA=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E5=A5=BD=E7=9B=B4=E6=92=AD=E5=8A=9F=E8=83=BD+=E6=9C=AA?= =?UTF-8?q?=E9=83=A8=E7=BD=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../example/livestreaming/MainActivity.java | 17 ++- .../java/com/example/livestreaming/Post.java | 61 ++++++++ .../example/livestreaming/PostAdapter.java | 80 ++++++++++ .../example/livestreaming/PostManager.java | 43 ++++++ .../livestreaming/PublishPostHelper.java | 43 ++++++ .../example/livestreaming/RoomAdapter.java | 96 ++++++++++++ .../livestreaming/RoomDetailActivity.java | 64 ++++++-- .../net/ConversationResponse.java | 47 +++--- .../livestreaming/net/PageResponse.java | 32 ++-- .../src/main/res/drawable/bg_trunk_text.xml | 6 + .../src/main/res/drawable/bg_wish_card.xml | 9 ++ .../main/res/drawable/bg_wish_card_add.xml | 11 ++ .../src/main/res/layout/dialog_make_wish.xml | 24 +++ .../main/res/layout/dialog_wish_success.xml | 28 ++++ .../app/src/main/res/layout/item_post.xml | 81 ++++++++++ .../app/src/main/res/layout/item_room.xml | 143 +++++++----------- 16 files changed, 638 insertions(+), 147 deletions(-) create mode 100644 android-app/app/src/main/java/com/example/livestreaming/Post.java create mode 100644 android-app/app/src/main/java/com/example/livestreaming/PostAdapter.java create mode 100644 android-app/app/src/main/java/com/example/livestreaming/PostManager.java create mode 100644 android-app/app/src/main/java/com/example/livestreaming/PublishPostHelper.java create mode 100644 android-app/app/src/main/java/com/example/livestreaming/RoomAdapter.java create mode 100644 android-app/app/src/main/res/drawable/bg_trunk_text.xml create mode 100644 android-app/app/src/main/res/drawable/bg_wish_card.xml create mode 100644 android-app/app/src/main/res/drawable/bg_wish_card_add.xml create mode 100644 android-app/app/src/main/res/layout/dialog_make_wish.xml create mode 100644 android-app/app/src/main/res/layout/dialog_wish_success.xml create mode 100644 android-app/app/src/main/res/layout/item_post.xml diff --git a/android-app/app/src/main/java/com/example/livestreaming/MainActivity.java b/android-app/app/src/main/java/com/example/livestreaming/MainActivity.java index ec5d60a4..d1d9dd38 100644 --- a/android-app/app/src/main/java/com/example/livestreaming/MainActivity.java +++ b/android-app/app/src/main/java/com/example/livestreaming/MainActivity.java @@ -44,7 +44,9 @@ import com.google.android.material.textfield.MaterialAutoCompleteTextView; import com.google.android.material.textfield.TextInputLayout; import com.example.livestreaming.net.ApiClient; import com.example.livestreaming.net.ApiResponse; +import com.example.livestreaming.net.ConversationResponse; import com.example.livestreaming.net.CreateRoomRequest; +import com.example.livestreaming.net.PageResponse; import com.example.livestreaming.net.Room; import com.example.livestreaming.net.StreamConfig; @@ -52,6 +54,7 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Map; import retrofit2.Call; import retrofit2.Callback; @@ -1826,7 +1829,19 @@ public class MainActivity extends AppCompatActivity { /** * 获取所有直播间并筛选出关注用户的直播间 */ - private void fetchAndFilterFollowRooms(List> + private void fetchAndFilterFollowRooms(List> followList) { + // 从关注列表中提取用户ID + if (followList == null || followList.isEmpty()) { + if (adapter != null) { + adapter.submitList(new ArrayList<>()); + } + return; + } + // TODO: 实现根据关注列表筛选直播间 + if (adapter != null) { + adapter.submitList(new ArrayList<>()); + } + } /** * 构建发现页面的房间列表(推荐算法前端实现) diff --git a/android-app/app/src/main/java/com/example/livestreaming/Post.java b/android-app/app/src/main/java/com/example/livestreaming/Post.java new file mode 100644 index 00000000..ff78129a --- /dev/null +++ b/android-app/app/src/main/java/com/example/livestreaming/Post.java @@ -0,0 +1,61 @@ +package com.example.livestreaming; + +import java.io.Serializable; + +public class Post implements Serializable { + private String id; + private String userId; + private String userName; + private String userAvatar; + private String content; + private String imageUrl; + private String category; + private long timestamp; + private int likeCount; + private int commentCount; + private boolean isLiked; + + public Post() {} + + public Post(String id, String userId, String userName, String content, String category) { + this.id = id; + this.userId = userId; + this.userName = userName; + this.content = content; + this.category = category; + this.timestamp = System.currentTimeMillis(); + } + + public String getId() { return id; } + public void setId(String id) { this.id = id; } + + public String getUserId() { return userId; } + public void setUserId(String userId) { this.userId = userId; } + + public String getUserName() { return userName; } + public void setUserName(String userName) { this.userName = userName; } + + public String getUserAvatar() { return userAvatar; } + public void setUserAvatar(String userAvatar) { this.userAvatar = userAvatar; } + + public String getContent() { return content; } + public void setContent(String content) { this.content = content; } + + public String getImageUrl() { return imageUrl; } + public void setImageUrl(String imageUrl) { this.imageUrl = imageUrl; } + + public String getCategory() { return category; } + public void setCategory(String category) { this.category = category; } + + public long getTimestamp() { return timestamp; } + public void setTimestamp(long timestamp) { this.timestamp = timestamp; } + + public int getLikeCount() { return likeCount; } + public void setLikeCount(int likeCount) { this.likeCount = likeCount; } + + public int getCommentCount() { return commentCount; } + public void setCommentCount(int commentCount) { this.commentCount = commentCount; } + + public boolean isLiked() { return isLiked; } + public void setLiked(boolean liked) { isLiked = liked; } +} diff --git a/android-app/app/src/main/java/com/example/livestreaming/PostAdapter.java b/android-app/app/src/main/java/com/example/livestreaming/PostAdapter.java new file mode 100644 index 00000000..56b4e7fa --- /dev/null +++ b/android-app/app/src/main/java/com/example/livestreaming/PostAdapter.java @@ -0,0 +1,80 @@ +package com.example.livestreaming; + +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.recyclerview.widget.RecyclerView; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Locale; + +public class PostAdapter extends RecyclerView.Adapter { + + private List posts = new ArrayList<>(); + + public void setPosts(List posts) { + this.posts = posts != null ? posts : new ArrayList<>(); + notifyDataSetChanged(); + } + + public void addPost(Post post) { + if (post != null) { + posts.add(0, post); + notifyItemInserted(0); + } + } + + @NonNull + @Override + public PostViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(parent.getContext()) + .inflate(R.layout.item_post, parent, false); + return new PostViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull PostViewHolder holder, int position) { + Post post = posts.get(position); + holder.bind(post); + } + + @Override + public int getItemCount() { + return posts.size(); + } + + static class PostViewHolder extends RecyclerView.ViewHolder { + private final TextView tvUserName; + private final TextView tvContent; + private final TextView tvTime; + private final TextView tvLikeCount; + private final TextView tvCommentCount; + + public PostViewHolder(@NonNull View itemView) { + super(itemView); + tvUserName = itemView.findViewById(R.id.tv_user_name); + tvContent = itemView.findViewById(R.id.tv_content); + tvTime = itemView.findViewById(R.id.tv_time); + tvLikeCount = itemView.findViewById(R.id.tv_like_count); + tvCommentCount = itemView.findViewById(R.id.tv_comment_count); + } + + public void bind(Post post) { + if (tvUserName != null) tvUserName.setText(post.getUserName()); + if (tvContent != null) tvContent.setText(post.getContent()); + if (tvTime != null) { + SimpleDateFormat sdf = new SimpleDateFormat("MM-dd HH:mm", Locale.getDefault()); + tvTime.setText(sdf.format(new Date(post.getTimestamp()))); + } + if (tvLikeCount != null) tvLikeCount.setText(String.valueOf(post.getLikeCount())); + if (tvCommentCount != null) tvCommentCount.setText(String.valueOf(post.getCommentCount())); + } + } +} diff --git a/android-app/app/src/main/java/com/example/livestreaming/PostManager.java b/android-app/app/src/main/java/com/example/livestreaming/PostManager.java new file mode 100644 index 00000000..47bab8ea --- /dev/null +++ b/android-app/app/src/main/java/com/example/livestreaming/PostManager.java @@ -0,0 +1,43 @@ +package com.example.livestreaming; + +import android.content.Context; +import android.content.SharedPreferences; + +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; + +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +public class PostManager { + private static final String PREFS_NAME = "posts_prefs"; + private static final String KEY_POSTS = "posts"; + private static final Gson gson = new Gson(); + + public static void savePost(Context context, Post post) { + List posts = getAllPosts(context); + posts.add(0, post); + savePosts(context, posts); + } + + public static List getAllPosts(Context context) { + SharedPreferences prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE); + String json = prefs.getString(KEY_POSTS, "[]"); + Type type = new TypeToken>(){}.getType(); + List posts = gson.fromJson(json, type); + return posts != null ? posts : new ArrayList<>(); + } + + public static List getPostsByCategory(Context context, String category) { + return getAllPosts(context).stream() + .filter(p -> category.equals(p.getCategory())) + .collect(Collectors.toList()); + } + + private static void savePosts(Context context, List posts) { + SharedPreferences prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE); + prefs.edit().putString(KEY_POSTS, gson.toJson(posts)).apply(); + } +} diff --git a/android-app/app/src/main/java/com/example/livestreaming/PublishPostHelper.java b/android-app/app/src/main/java/com/example/livestreaming/PublishPostHelper.java new file mode 100644 index 00000000..50dadc6b --- /dev/null +++ b/android-app/app/src/main/java/com/example/livestreaming/PublishPostHelper.java @@ -0,0 +1,43 @@ +package com.example.livestreaming; + +import android.app.Activity; +import android.app.AlertDialog; +import android.widget.EditText; +import android.widget.Toast; + +public class PublishPostHelper { + + public interface PublishCallback { + void onSuccess(Post post); + void onError(String error); + } + + public static void showPublishDialog(Activity activity, String category, PublishCallback callback) { + EditText input = new EditText(activity); + input.setHint("输入内容..."); + + new AlertDialog.Builder(activity) + .setTitle("发布动态") + .setView(input) + .setPositiveButton("发布", (dialog, which) -> { + String content = input.getText().toString().trim(); + if (content.isEmpty()) { + Toast.makeText(activity, "内容不能为空", Toast.LENGTH_SHORT).show(); + return; + } + Post post = new Post(); + post.setId(String.valueOf(System.currentTimeMillis())); + post.setContent(content); + post.setCategory(category); + post.setUserName("用户"); + post.setTimestamp(System.currentTimeMillis()); + + PostManager.savePost(activity, post); + if (callback != null) { + callback.onSuccess(post); + } + }) + .setNegativeButton("取消", null) + .show(); + } +} diff --git a/android-app/app/src/main/java/com/example/livestreaming/RoomAdapter.java b/android-app/app/src/main/java/com/example/livestreaming/RoomAdapter.java new file mode 100644 index 00000000..5ec76b26 --- /dev/null +++ b/android-app/app/src/main/java/com/example/livestreaming/RoomAdapter.java @@ -0,0 +1,96 @@ +package com.example.livestreaming; + +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.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 RoomAdapter extends ListAdapter { + + private OnRoomClickListener listener; + + public interface OnRoomClickListener { + void onRoomClick(Room room); + } + + public RoomAdapter() { + super(new DiffUtil.ItemCallback() { + @Override + public boolean areItemsTheSame(@NonNull Room oldItem, @NonNull Room newItem) { + return oldItem.getId() != null && oldItem.getId().equals(newItem.getId()); + } + + @Override + public boolean areContentsTheSame(@NonNull Room oldItem, @NonNull Room newItem) { + return oldItem.equals(newItem); + } + }); + } + + public void setOnRoomClickListener(OnRoomClickListener listener) { + this.listener = listener; + } + + @NonNull + @Override + public RoomViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(parent.getContext()) + .inflate(R.layout.item_room, parent, false); + return new RoomViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull RoomViewHolder holder, int position) { + Room room = getItem(position); + holder.bind(room, listener); + } + + static class RoomViewHolder extends RecyclerView.ViewHolder { + private final TextView tvTitle; + private final TextView tvStreamer; + private final TextView tvLikeCount; + private final ImageView ivCover; + private final View liveIndicator; + + public RoomViewHolder(@NonNull View itemView) { + super(itemView); + tvTitle = itemView.findViewById(R.id.roomTitle); + tvStreamer = itemView.findViewById(R.id.streamerName); + tvLikeCount = itemView.findViewById(R.id.likeCount); + ivCover = itemView.findViewById(R.id.coverImage); + liveIndicator = itemView.findViewById(R.id.liveBadge); + } + + public void bind(Room room, OnRoomClickListener listener) { + if (tvTitle != null) tvTitle.setText(room.getTitle()); + if (tvStreamer != null) tvStreamer.setText(room.getStreamerName()); + if (tvLikeCount != null) tvLikeCount.setText(String.valueOf(room.getViewerCount())); + + if (liveIndicator != null) { + liveIndicator.setVisibility(room.isLive() ? View.VISIBLE : View.GONE); + } + + if (ivCover != null && room.getCoverImage() != null) { + Glide.with(itemView.getContext()) + .load(room.getCoverImage()) + .placeholder(android.R.drawable.ic_menu_gallery) + .into(ivCover); + } + + itemView.setOnClickListener(v -> { + if (listener != null) { + listener.onRoomClick(room); + } + }); + } + } +} diff --git a/android-app/app/src/main/java/com/example/livestreaming/RoomDetailActivity.java b/android-app/app/src/main/java/com/example/livestreaming/RoomDetailActivity.java index fa33d121..eb0afe5e 100644 --- a/android-app/app/src/main/java/com/example/livestreaming/RoomDetailActivity.java +++ b/android-app/app/src/main/java/com/example/livestreaming/RoomDetailActivity.java @@ -100,12 +100,28 @@ public class RoomDetailActivity extends AppCompatActivity { // WebSocket - 弹幕 private WebSocket chatWebSocket; private OkHttpClient chatWsClient; - private static final String WS_CHAT_BASE_URL = "ws://192.168.1.164:8081/ws/live/chat/"; // WebSocket - 在线人数 private WebSocket onlineCountWebSocket; private OkHttpClient onlineCountWsClient; - private static final String WS_ONLINE_BASE_URL = "ws://192.168.1.164:8081/ws/live/"; + + // 动态获取WebSocket URL + private String getWsChatBaseUrl() { + String baseUrl = ApiClient.getCurrentBaseUrl(this); + if (baseUrl == null || baseUrl.isEmpty()) { + baseUrl = "http://192.168.1.164:8081/"; + } + // 将 http:// 转换为 ws:// + return baseUrl.replace("http://", "ws://").replace("https://", "wss://") + "ws/live/chat/"; + } + + private String getWsOnlineBaseUrl() { + String baseUrl = ApiClient.getCurrentBaseUrl(this); + if (baseUrl == null || baseUrl.isEmpty()) { + baseUrl = "http://192.168.1.164:8081/"; + } + return baseUrl.replace("http://", "ws://").replace("https://", "wss://") + "ws/live/"; + } // WebSocket 心跳检测 - 弹幕 private Runnable chatHeartbeatRunnable; @@ -265,7 +281,7 @@ public class RoomDetailActivity extends AppCompatActivity { .pingInterval(30, java.util.concurrent.TimeUnit.SECONDS) // OkHttp 内置 ping .build(); Request request = new Request.Builder() - .url(WS_CHAT_BASE_URL + roomId) + .url(getWsChatBaseUrl() + roomId) .build(); chatWebSocket = chatWsClient.newWebSocket(request, new WebSocketListener() { @@ -372,7 +388,7 @@ public class RoomDetailActivity extends AppCompatActivity { String clientId = (userIdStr != null && !userIdStr.isEmpty()) ? userIdStr : "guest_" + System.currentTimeMillis(); - String wsUrl = WS_ONLINE_BASE_URL + roomId + "?clientId=" + clientId; + String wsUrl = getWsOnlineBaseUrl() + roomId + "?clientId=" + clientId; onlineCountWsClient = new OkHttpClient.Builder() .pingInterval(30, java.util.concurrent.TimeUnit.SECONDS) @@ -1050,14 +1066,19 @@ public class RoomDetailActivity extends AppCompatActivity { if (ijkSurface == null) return; IjkMediaPlayer p = new IjkMediaPlayer(); - p.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "packet-buffering", 0); + // 优化缓冲设置,减少卡顿 + p.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "packet-buffering", 1); // 开启缓冲 p.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "start-on-prepared", 1); p.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "fflags", "nobuffer"); - p.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "analyzeduration", 1); - p.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "probesize", 1024); - p.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "framedrop", 1); - p.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "max_cached_duration", 300); - p.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "infbuf", 1); + p.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "analyzeduration", 100000); // 100ms分析时长 + p.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "probesize", 10240); // 10KB探测大小 + p.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "framedrop", 5); // 允许丢帧 + p.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "max_cached_duration", 3000); // 3秒缓存 + p.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "min_frames", 50); // 最小缓冲帧数 + p.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "infbuf", 0); // 关闭无限缓冲 + p.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "reconnect", 1); // 断线重连 + p.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "reconnect_streamed", 1); + p.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "reconnect_delay_max", 5); // 最大重连延迟5秒 p.setOnPreparedListener(mp -> { binding.offlineLayout.setVisibility(View.GONE); @@ -1066,14 +1087,36 @@ public class RoomDetailActivity extends AppCompatActivity { }); p.setOnErrorListener((IMediaPlayer mp, int what, int extra) -> { + android.util.Log.e("IjkPlayer", "播放错误: what=" + what + ", extra=" + extra); if (ijkFallbackTried || TextUtils.isEmpty(ijkFallbackHlsUrl)) { binding.offlineLayout.setVisibility(View.VISIBLE); + // 5秒后尝试重新连接 + handler.postDelayed(() -> { + if (!isFinishing() && !isDestroyed() && room != null && room.isLive()) { + fetchRoom(); // 重新获取房间信息并播放 + } + }, 5000); return true; } ijkFallbackTried = true; startHls(ijkFallbackHlsUrl, null); return true; }); + + // 添加缓冲监听 + p.setOnInfoListener((mp, what, extra) -> { + if (what == IMediaPlayer.MEDIA_INFO_BUFFERING_START) { + android.util.Log.d("IjkPlayer", "开始缓冲..."); + // 可以显示加载指示器 + } else if (what == IMediaPlayer.MEDIA_INFO_BUFFERING_END) { + android.util.Log.d("IjkPlayer", "缓冲结束"); + // 隐藏加载指示器 + } else if (what == IMediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START) { + android.util.Log.d("IjkPlayer", "视频开始渲染"); + binding.offlineLayout.setVisibility(View.GONE); + } + return false; + }); ijkPlayer = p; try { @@ -1081,6 +1124,7 @@ public class RoomDetailActivity extends AppCompatActivity { p.setDataSource(url); p.prepareAsync(); } catch (Exception e) { + android.util.Log.e("IjkPlayer", "播放器初始化失败: " + e.getMessage()); if (!TextUtils.isEmpty(ijkFallbackHlsUrl)) { startHls(ijkFallbackHlsUrl, null); } else { diff --git a/android-app/app/src/main/java/com/example/livestreaming/net/ConversationResponse.java b/android-app/app/src/main/java/com/example/livestreaming/net/ConversationResponse.java index 6c4b9b69..6a100d2f 100644 --- a/android-app/app/src/main/java/com/example/livestreaming/net/ConversationResponse.java +++ b/android-app/app/src/main/java/com/example/livestreaming/net/ConversationResponse.java @@ -1,39 +1,32 @@ package com.example.livestreaming.net; -import com.google.gson.annotations.SerializedName; - public class ConversationResponse { - - @SerializedName("id") - private String id; - - @SerializedName("title") - private String title; - - @SerializedName("lastMessage") + private Integer id; + private Integer targetUserId; + private String targetUserName; + private String targetUserAvatar; private String lastMessage; - - @SerializedName("timeText") - private String timeText; - - @SerializedName("unreadCount") + private String lastMessageTime; private Integer unreadCount; - @SerializedName("muted") - private Boolean muted; + public Integer getId() { return id; } + public void setId(Integer id) { this.id = id; } - @SerializedName("avatarUrl") - private String avatarUrl; + public Integer getTargetUserId() { return targetUserId; } + public void setTargetUserId(Integer targetUserId) { this.targetUserId = targetUserId; } - @SerializedName("otherUserId") - private Integer otherUserId; + public String getTargetUserName() { return targetUserName; } + public void setTargetUserName(String targetUserName) { this.targetUserName = targetUserName; } + + public String getTargetUserAvatar() { return targetUserAvatar; } + public void setTargetUserAvatar(String targetUserAvatar) { this.targetUserAvatar = targetUserAvatar; } - public String getId() { return id; } - public String getTitle() { return title; } public String getLastMessage() { return lastMessage; } - public String getTimeText() { return timeText; } + public void setLastMessage(String lastMessage) { this.lastMessage = lastMessage; } + + public String getLastMessageTime() { return lastMessageTime; } + public void setLastMessageTime(String lastMessageTime) { this.lastMessageTime = lastMessageTime; } + public Integer getUnreadCount() { return unreadCount; } - public Boolean getMuted() { return muted; } - public String getAvatarUrl() { return avatarUrl; } - public Integer getOtherUserId() { return otherUserId; } + public void setUnreadCount(Integer unreadCount) { this.unreadCount = unreadCount; } } diff --git a/android-app/app/src/main/java/com/example/livestreaming/net/PageResponse.java b/android-app/app/src/main/java/com/example/livestreaming/net/PageResponse.java index a7cfb5b1..2b5c91bb 100644 --- a/android-app/app/src/main/java/com/example/livestreaming/net/PageResponse.java +++ b/android-app/app/src/main/java/com/example/livestreaming/net/PageResponse.java @@ -1,32 +1,26 @@ package com.example.livestreaming.net; -import com.google.gson.annotations.SerializedName; import java.util.List; public class PageResponse { - - @SerializedName("list") private List list; - - @SerializedName("total") - private Long total; - - @SerializedName("page") private Integer page; - - @SerializedName("limit") private Integer limit; - - @SerializedName("totalPage") + private Integer total; private Integer totalPage; public List getList() { return list; } - public Long getTotal() { return total; } - public Integer getPage() { return page; } - public Integer getLimit() { return limit; } - public Integer getTotalPage() { return totalPage; } + public void setList(List list) { this.list = list; } - public boolean hasMore() { - return page != null && totalPage != null && page < totalPage; - } + public Integer getPage() { return page; } + public void setPage(Integer page) { this.page = page; } + + public Integer getLimit() { return limit; } + public void setLimit(Integer limit) { this.limit = limit; } + + public Integer getTotal() { return total; } + public void setTotal(Integer total) { this.total = total; } + + public Integer getTotalPage() { return totalPage; } + public void setTotalPage(Integer totalPage) { this.totalPage = totalPage; } } diff --git a/android-app/app/src/main/res/drawable/bg_trunk_text.xml b/android-app/app/src/main/res/drawable/bg_trunk_text.xml new file mode 100644 index 00000000..44d0ceaa --- /dev/null +++ b/android-app/app/src/main/res/drawable/bg_trunk_text.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/android-app/app/src/main/res/drawable/bg_wish_card.xml b/android-app/app/src/main/res/drawable/bg_wish_card.xml new file mode 100644 index 00000000..6e7671dc --- /dev/null +++ b/android-app/app/src/main/res/drawable/bg_wish_card.xml @@ -0,0 +1,9 @@ + + + + + + diff --git a/android-app/app/src/main/res/drawable/bg_wish_card_add.xml b/android-app/app/src/main/res/drawable/bg_wish_card_add.xml new file mode 100644 index 00000000..3a582b36 --- /dev/null +++ b/android-app/app/src/main/res/drawable/bg_wish_card_add.xml @@ -0,0 +1,11 @@ + + + + + + diff --git a/android-app/app/src/main/res/layout/dialog_make_wish.xml b/android-app/app/src/main/res/layout/dialog_make_wish.xml new file mode 100644 index 00000000..da09d37d --- /dev/null +++ b/android-app/app/src/main/res/layout/dialog_make_wish.xml @@ -0,0 +1,24 @@ + + + + + + + diff --git a/android-app/app/src/main/res/layout/dialog_wish_success.xml b/android-app/app/src/main/res/layout/dialog_wish_success.xml new file mode 100644 index 00000000..664c13ed --- /dev/null +++ b/android-app/app/src/main/res/layout/dialog_wish_success.xml @@ -0,0 +1,28 @@ + + + + + + + + + diff --git a/android-app/app/src/main/res/layout/item_post.xml b/android-app/app/src/main/res/layout/item_post.xml new file mode 100644 index 00000000..6ae30f47 --- /dev/null +++ b/android-app/app/src/main/res/layout/item_post.xml @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android-app/app/src/main/res/layout/item_room.xml b/android-app/app/src/main/res/layout/item_room.xml index 4136b8ab..7f4fd547 100644 --- a/android-app/app/src/main/res/layout/item_room.xml +++ b/android-app/app/src/main/res/layout/item_room.xml @@ -1,119 +1,82 @@ - + android:layout_margin="4dp" + app:cardCornerRadius="8dp" + app:cardElevation="2dp"> - + android:layout_width="match_parent" + android:layout_height="120dp" + android:scaleType="centerCrop" /> + android:textSize="10sp" + android:visibility="gone" /> - + android:layout_gravity="bottom" + android:background="#80000000" + android:orientation="vertical" + android:padding="8dp"> - - - - + android:textColor="@android:color/white" + android:textSize="14sp" /> - - - + android:orientation="horizontal"> - + - + - + + + + +