Compare commits

...

3 Commits

Author SHA1 Message Date
userName
eb5daad9de 缘池,和许愿树的内容 2025-12-30 17:57:42 +08:00
userName
e2b4d04420 Merge branch 'master' of http://115.190.64.57:8000/xiaozhang/zhibo 2025-12-30 17:42:43 +08:00
userName
3e90031acf 缘池,和许愿树的内容 2025-12-30 17:33:27 +08:00
19 changed files with 1192 additions and 166 deletions

View File

@ -181,26 +181,23 @@ public class CategoryManagementActivity extends AppCompatActivity {
private void loadCategoryStatistics() { private void loadCategoryStatistics() {
// 获取直播间分类统计type=8 // 获取直播间分类统计type=8
ApiClient.getService(this).getCategoryStatistics(8) ApiClient.getService(this).getCategoryStatistics(8)
.enqueue(new Callback<ApiResponse<List<Map<String, Object>>>>() { .enqueue(new Callback<ApiResponse<Map<String, Object>>>() {
@Override @Override
public void onResponse(Call<ApiResponse<List<Map<String, Object>>>> call, public void onResponse(Call<ApiResponse<Map<String, Object>>> call,
Response<ApiResponse<List<Map<String, Object>>>> response) { Response<ApiResponse<Map<String, Object>>> response) {
ApiResponse<List<Map<String, Object>>> body = response.body(); ApiResponse<Map<String, Object>> body = response.body();
List<Map<String, Object>> statistics = Map<String, Object> statistics =
response.isSuccessful() && body != null && body.isOk() && body.getData() != null response.isSuccessful() && body != null && body.isOk() && body.getData() != null
? body.getData() ? body.getData()
: null; : null;
if (statistics != null && !statistics.isEmpty()) { if (statistics != null && !statistics.isEmpty()) {
Log.d(TAG, "获取到 " + statistics.size() + " 个分类统计"); Log.d(TAG, "获取到分类统计: " + statistics.toString());
for (Map<String, Object> stat : statistics) {
Log.d(TAG, "统计: " + stat.toString());
}
} }
} }
@Override @Override
public void onFailure(Call<ApiResponse<List<Map<String, Object>>>> call, Throwable t) { public void onFailure(Call<ApiResponse<Map<String, Object>>> call, Throwable t) {
Log.e(TAG, "获取分类统计失败: " + t.getMessage(), t); Log.e(TAG, "获取分类统计失败: " + t.getMessage(), t);
} }
}); });

View File

@ -3,15 +3,21 @@ package com.example.livestreaming;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.view.View;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import com.example.livestreaming.databinding.ActivityDrawGuessBinding; import com.example.livestreaming.databinding.ActivityDrawGuessBinding;
import com.google.android.material.bottomnavigation.BottomNavigationView; import com.google.android.material.bottomnavigation.BottomNavigationView;
import java.util.List;
public class DrawGuessActivity extends AppCompatActivity { public class DrawGuessActivity extends AppCompatActivity {
private static final String CATEGORY = "你画我猜";
private ActivityDrawGuessBinding binding; private ActivityDrawGuessBinding binding;
private PostAdapter postAdapter;
public static void start(Context context) { public static void start(Context context) {
Intent intent = new Intent(context, DrawGuessActivity.class); Intent intent = new Intent(context, DrawGuessActivity.class);
@ -25,15 +31,29 @@ public class DrawGuessActivity extends AppCompatActivity {
setContentView(binding.getRoot()); setContentView(binding.getRoot());
setupUI(); setupUI();
setupRecyclerView();
loadPosts();
} }
private void setupUI() { private void setupUI() {
binding.backButton.setOnClickListener(v -> finish()); binding.backButton.setOnClickListener(v -> finish());
binding.fabPublish.setOnClickListener(v -> {
PublishPostHelper.showPublishDialog(this, CATEGORY, new PublishPostHelper.PublishCallback() {
@Override
public void onSuccess(Post post) {
postAdapter.addPost(post);
binding.recyclerPosts.scrollToPosition(0);
updateEmptyView();
}
@Override
public void onError(String error) {}
});
});
BottomNavigationView bottomNavigation = binding.bottomNavInclude.bottomNavigation; BottomNavigationView bottomNavigation = binding.bottomNavInclude.bottomNavigation;
bottomNavigation.setSelectedItemId(R.id.nav_friends); bottomNavigation.setSelectedItemId(R.id.nav_friends);
// 更新未读消息徽章
UnreadMessageManager.updateBadge(bottomNavigation); UnreadMessageManager.updateBadge(bottomNavigation);
bottomNavigation.setOnItemSelectedListener(item -> { bottomNavigation.setOnItemSelectedListener(item -> {
@ -62,15 +82,36 @@ public class DrawGuessActivity extends AppCompatActivity {
}); });
} }
private void setupRecyclerView() {
postAdapter = new PostAdapter();
binding.recyclerPosts.setLayoutManager(new LinearLayoutManager(this));
binding.recyclerPosts.setAdapter(postAdapter);
}
private void loadPosts() {
List<Post> posts = PostManager.getPostsByCategory(this, CATEGORY);
postAdapter.setPosts(posts);
updateEmptyView();
}
private void updateEmptyView() {
if (postAdapter.getItemCount() == 0) {
binding.emptyView.setVisibility(View.VISIBLE);
binding.recyclerPosts.setVisibility(View.GONE);
} else {
binding.emptyView.setVisibility(View.GONE);
binding.recyclerPosts.setVisibility(View.VISIBLE);
}
}
@Override @Override
protected void onResume() { protected void onResume() {
super.onResume(); super.onResume();
if (binding != null) { if (binding != null) {
BottomNavigationView bottomNav = binding.bottomNavInclude.bottomNavigation; BottomNavigationView bottomNav = binding.bottomNavInclude.bottomNavigation;
bottomNav.setSelectedItemId(R.id.nav_friends); bottomNav.setSelectedItemId(R.id.nav_friends);
// 更新未读消息徽章
UnreadMessageManager.updateBadge(bottomNav); UnreadMessageManager.updateBadge(bottomNav);
loadPosts();
} }
} }
} }

View File

@ -3,15 +3,21 @@ package com.example.livestreaming;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.view.View;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import com.example.livestreaming.databinding.ActivityFindGameBinding; import com.example.livestreaming.databinding.ActivityFindGameBinding;
import com.google.android.material.bottomnavigation.BottomNavigationView; import com.google.android.material.bottomnavigation.BottomNavigationView;
import java.util.List;
public class FindGameActivity extends AppCompatActivity { public class FindGameActivity extends AppCompatActivity {
private static final String CATEGORY = "找人玩游戏";
private ActivityFindGameBinding binding; private ActivityFindGameBinding binding;
private PostAdapter postAdapter;
public static void start(Context context) { public static void start(Context context) {
Intent intent = new Intent(context, FindGameActivity.class); Intent intent = new Intent(context, FindGameActivity.class);
@ -25,15 +31,29 @@ public class FindGameActivity extends AppCompatActivity {
setContentView(binding.getRoot()); setContentView(binding.getRoot());
setupUI(); setupUI();
setupRecyclerView();
loadPosts();
} }
private void setupUI() { private void setupUI() {
binding.backButton.setOnClickListener(v -> finish()); binding.backButton.setOnClickListener(v -> finish());
binding.fabPublish.setOnClickListener(v -> {
PublishPostHelper.showPublishDialog(this, CATEGORY, new PublishPostHelper.PublishCallback() {
@Override
public void onSuccess(Post post) {
postAdapter.addPost(post);
binding.recyclerPosts.scrollToPosition(0);
updateEmptyView();
}
@Override
public void onError(String error) {}
});
});
BottomNavigationView bottomNavigation = binding.bottomNavInclude.bottomNavigation; BottomNavigationView bottomNavigation = binding.bottomNavInclude.bottomNavigation;
bottomNavigation.setSelectedItemId(R.id.nav_friends); bottomNavigation.setSelectedItemId(R.id.nav_friends);
// 更新未读消息徽章
UnreadMessageManager.updateBadge(bottomNavigation); UnreadMessageManager.updateBadge(bottomNavigation);
bottomNavigation.setOnItemSelectedListener(item -> { bottomNavigation.setOnItemSelectedListener(item -> {
@ -62,15 +82,36 @@ public class FindGameActivity extends AppCompatActivity {
}); });
} }
private void setupRecyclerView() {
postAdapter = new PostAdapter();
binding.recyclerPosts.setLayoutManager(new LinearLayoutManager(this));
binding.recyclerPosts.setAdapter(postAdapter);
}
private void loadPosts() {
List<Post> posts = PostManager.getPostsByCategory(this, CATEGORY);
postAdapter.setPosts(posts);
updateEmptyView();
}
private void updateEmptyView() {
if (postAdapter.getItemCount() == 0) {
binding.emptyView.setVisibility(View.VISIBLE);
binding.recyclerPosts.setVisibility(View.GONE);
} else {
binding.emptyView.setVisibility(View.GONE);
binding.recyclerPosts.setVisibility(View.VISIBLE);
}
}
@Override @Override
protected void onResume() { protected void onResume() {
super.onResume(); super.onResume();
if (binding != null) { if (binding != null) {
BottomNavigationView bottomNav = binding.bottomNavInclude.bottomNavigation; BottomNavigationView bottomNav = binding.bottomNavInclude.bottomNavigation;
bottomNav.setSelectedItemId(R.id.nav_friends); bottomNav.setSelectedItemId(R.id.nav_friends);
// 更新未读消息徽章
UnreadMessageManager.updateBadge(bottomNav); UnreadMessageManager.updateBadge(bottomNav);
loadPosts();
} }
} }
} }

View File

@ -95,7 +95,12 @@ public class GroupDetailActivity extends AppCompatActivity {
membersAdapter = new GroupMembersAdapter(item -> { membersAdapter = new GroupMembersAdapter(item -> {
if (item == null) return; if (item == null) return;
// 点击成员查看资料 // 点击成员查看资料
UserProfileReadOnlyActivity.start(this, item.getUserId()); UserProfileReadOnlyActivity.start(this,
String.valueOf(item.getUserId()),
item.getNickname(),
"",
"",
0);
}); });
membersAdapter.setOnMemberLongClickListener(item -> { membersAdapter.setOnMemberLongClickListener(item -> {
if (item == null) return; if (item == null) return;
@ -277,7 +282,12 @@ public class GroupDetailActivity extends AppCompatActivity {
.setTitle(member.getNickname()) .setTitle(member.getNickname())
.setItems(options, (dialog, which) -> { .setItems(options, (dialog, which) -> {
if (which == 0) { if (which == 0) {
UserProfileReadOnlyActivity.start(this, member.getUserId()); UserProfileReadOnlyActivity.start(this,
String.valueOf(member.getUserId()),
member.getNickname(),
"",
"",
0);
} else if (which == 1) { } else if (which == 1) {
showRemoveMemberDialog(member); showRemoveMemberDialog(member);
} }

View File

@ -3,15 +3,21 @@ package com.example.livestreaming;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.view.View;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import com.example.livestreaming.databinding.ActivityKtvTogetherBinding; import com.example.livestreaming.databinding.ActivityKtvTogetherBinding;
import com.google.android.material.bottomnavigation.BottomNavigationView; import com.google.android.material.bottomnavigation.BottomNavigationView;
import java.util.List;
public class KTVTogetherActivity extends AppCompatActivity { public class KTVTogetherActivity extends AppCompatActivity {
private static final String CATEGORY = "一起KTV";
private ActivityKtvTogetherBinding binding; private ActivityKtvTogetherBinding binding;
private PostAdapter postAdapter;
public static void start(Context context) { public static void start(Context context) {
Intent intent = new Intent(context, KTVTogetherActivity.class); Intent intent = new Intent(context, KTVTogetherActivity.class);
@ -25,15 +31,29 @@ public class KTVTogetherActivity extends AppCompatActivity {
setContentView(binding.getRoot()); setContentView(binding.getRoot());
setupUI(); setupUI();
setupRecyclerView();
loadPosts();
} }
private void setupUI() { private void setupUI() {
binding.backButton.setOnClickListener(v -> finish()); binding.backButton.setOnClickListener(v -> finish());
binding.fabPublish.setOnClickListener(v -> {
PublishPostHelper.showPublishDialog(this, CATEGORY, new PublishPostHelper.PublishCallback() {
@Override
public void onSuccess(Post post) {
postAdapter.addPost(post);
binding.recyclerPosts.scrollToPosition(0);
updateEmptyView();
}
@Override
public void onError(String error) {}
});
});
BottomNavigationView bottomNavigation = binding.bottomNavInclude.bottomNavigation; BottomNavigationView bottomNavigation = binding.bottomNavInclude.bottomNavigation;
bottomNavigation.setSelectedItemId(R.id.nav_friends); bottomNavigation.setSelectedItemId(R.id.nav_friends);
// 更新未读消息徽章
UnreadMessageManager.updateBadge(bottomNavigation); UnreadMessageManager.updateBadge(bottomNavigation);
bottomNavigation.setOnItemSelectedListener(item -> { bottomNavigation.setOnItemSelectedListener(item -> {
@ -62,15 +82,36 @@ public class KTVTogetherActivity extends AppCompatActivity {
}); });
} }
private void setupRecyclerView() {
postAdapter = new PostAdapter();
binding.recyclerPosts.setLayoutManager(new LinearLayoutManager(this));
binding.recyclerPosts.setAdapter(postAdapter);
}
private void loadPosts() {
List<Post> posts = PostManager.getPostsByCategory(this, CATEGORY);
postAdapter.setPosts(posts);
updateEmptyView();
}
private void updateEmptyView() {
if (postAdapter.getItemCount() == 0) {
binding.emptyView.setVisibility(View.VISIBLE);
binding.recyclerPosts.setVisibility(View.GONE);
} else {
binding.emptyView.setVisibility(View.GONE);
binding.recyclerPosts.setVisibility(View.VISIBLE);
}
}
@Override @Override
protected void onResume() { protected void onResume() {
super.onResume(); super.onResume();
if (binding != null) { if (binding != null) {
BottomNavigationView bottomNav = binding.bottomNavInclude.bottomNavigation; BottomNavigationView bottomNav = binding.bottomNavInclude.bottomNavigation;
bottomNav.setSelectedItemId(R.id.nav_friends); bottomNav.setSelectedItemId(R.id.nav_friends);
// 更新未读消息徽章
UnreadMessageManager.updateBadge(bottomNav); UnreadMessageManager.updateBadge(bottomNav);
loadPosts();
} }
} }
} }

View File

@ -3,15 +3,21 @@ package com.example.livestreaming;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.view.View;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import com.example.livestreaming.databinding.ActivityOnlineDatingBinding; import com.example.livestreaming.databinding.ActivityOnlineDatingBinding;
import com.google.android.material.bottomnavigation.BottomNavigationView; import com.google.android.material.bottomnavigation.BottomNavigationView;
import java.util.List;
public class OnlineDatingActivity extends AppCompatActivity { public class OnlineDatingActivity extends AppCompatActivity {
private static final String CATEGORY = "在线处对象";
private ActivityOnlineDatingBinding binding; private ActivityOnlineDatingBinding binding;
private PostAdapter postAdapter;
public static void start(Context context) { public static void start(Context context) {
Intent intent = new Intent(context, OnlineDatingActivity.class); Intent intent = new Intent(context, OnlineDatingActivity.class);
@ -25,11 +31,31 @@ public class OnlineDatingActivity extends AppCompatActivity {
setContentView(binding.getRoot()); setContentView(binding.getRoot());
setupUI(); setupUI();
setupRecyclerView();
loadPosts();
} }
private void setupUI() { private void setupUI() {
binding.backButton.setOnClickListener(v -> finish()); binding.backButton.setOnClickListener(v -> finish());
// 发布动态按钮
binding.fabPublish.setOnClickListener(v -> {
PublishPostHelper.showPublishDialog(this, CATEGORY, new PublishPostHelper.PublishCallback() {
@Override
public void onSuccess(Post post) {
// 发布成功添加到列表顶部
postAdapter.addPost(post);
binding.recyclerPosts.scrollToPosition(0);
updateEmptyView();
}
@Override
public void onError(String error) {
// 发布失败
}
});
});
BottomNavigationView bottomNavigation = binding.bottomNavInclude.bottomNavigation; BottomNavigationView bottomNavigation = binding.bottomNavInclude.bottomNavigation;
bottomNavigation.setSelectedItemId(R.id.nav_friends); bottomNavigation.setSelectedItemId(R.id.nav_friends);
@ -62,6 +88,29 @@ public class OnlineDatingActivity extends AppCompatActivity {
}); });
} }
private void setupRecyclerView() {
postAdapter = new PostAdapter();
binding.recyclerPosts.setLayoutManager(new LinearLayoutManager(this));
binding.recyclerPosts.setAdapter(postAdapter);
}
private void loadPosts() {
// 加载该分类的动态
List<Post> posts = PostManager.getPostsByCategory(this, CATEGORY);
postAdapter.setPosts(posts);
updateEmptyView();
}
private void updateEmptyView() {
if (postAdapter.getItemCount() == 0) {
binding.emptyView.setVisibility(View.VISIBLE);
binding.recyclerPosts.setVisibility(View.GONE);
} else {
binding.emptyView.setVisibility(View.GONE);
binding.recyclerPosts.setVisibility(View.VISIBLE);
}
}
@Override @Override
protected void onResume() { protected void onResume() {
super.onResume(); super.onResume();
@ -70,7 +119,8 @@ public class OnlineDatingActivity extends AppCompatActivity {
bottomNav.setSelectedItemId(R.id.nav_friends); bottomNav.setSelectedItemId(R.id.nav_friends);
// 更新未读消息徽章 // 更新未读消息徽章
UnreadMessageManager.updateBadge(bottomNav); UnreadMessageManager.updateBadge(bottomNav);
// 刷新动态列表
loadPosts();
} }
} }
} }

View File

@ -3,15 +3,21 @@ package com.example.livestreaming;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.view.View;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import com.example.livestreaming.databinding.ActivityPeaceEliteBinding; import com.example.livestreaming.databinding.ActivityPeaceEliteBinding;
import com.google.android.material.bottomnavigation.BottomNavigationView; import com.google.android.material.bottomnavigation.BottomNavigationView;
import java.util.List;
public class PeaceEliteActivity extends AppCompatActivity { public class PeaceEliteActivity extends AppCompatActivity {
private static final String CATEGORY = "和平精英";
private ActivityPeaceEliteBinding binding; private ActivityPeaceEliteBinding binding;
private PostAdapter postAdapter;
public static void start(Context context) { public static void start(Context context) {
Intent intent = new Intent(context, PeaceEliteActivity.class); Intent intent = new Intent(context, PeaceEliteActivity.class);
@ -25,15 +31,29 @@ public class PeaceEliteActivity extends AppCompatActivity {
setContentView(binding.getRoot()); setContentView(binding.getRoot());
setupUI(); setupUI();
setupRecyclerView();
loadPosts();
} }
private void setupUI() { private void setupUI() {
binding.backButton.setOnClickListener(v -> finish()); binding.backButton.setOnClickListener(v -> finish());
binding.fabPublish.setOnClickListener(v -> {
PublishPostHelper.showPublishDialog(this, CATEGORY, new PublishPostHelper.PublishCallback() {
@Override
public void onSuccess(Post post) {
postAdapter.addPost(post);
binding.recyclerPosts.scrollToPosition(0);
updateEmptyView();
}
@Override
public void onError(String error) {}
});
});
BottomNavigationView bottomNavigation = binding.bottomNavInclude.bottomNavigation; BottomNavigationView bottomNavigation = binding.bottomNavInclude.bottomNavigation;
bottomNavigation.setSelectedItemId(R.id.nav_friends); bottomNavigation.setSelectedItemId(R.id.nav_friends);
// 更新未读消息徽章
UnreadMessageManager.updateBadge(bottomNavigation); UnreadMessageManager.updateBadge(bottomNavigation);
bottomNavigation.setOnItemSelectedListener(item -> { bottomNavigation.setOnItemSelectedListener(item -> {
@ -62,15 +82,36 @@ public class PeaceEliteActivity extends AppCompatActivity {
}); });
} }
private void setupRecyclerView() {
postAdapter = new PostAdapter();
binding.recyclerPosts.setLayoutManager(new LinearLayoutManager(this));
binding.recyclerPosts.setAdapter(postAdapter);
}
private void loadPosts() {
List<Post> posts = PostManager.getPostsByCategory(this, CATEGORY);
postAdapter.setPosts(posts);
updateEmptyView();
}
private void updateEmptyView() {
if (postAdapter.getItemCount() == 0) {
binding.emptyView.setVisibility(View.VISIBLE);
binding.recyclerPosts.setVisibility(View.GONE);
} else {
binding.emptyView.setVisibility(View.GONE);
binding.recyclerPosts.setVisibility(View.VISIBLE);
}
}
@Override @Override
protected void onResume() { protected void onResume() {
super.onResume(); super.onResume();
if (binding != null) { if (binding != null) {
BottomNavigationView bottomNav = binding.bottomNavInclude.bottomNavigation; BottomNavigationView bottomNav = binding.bottomNavInclude.bottomNavigation;
bottomNav.setSelectedItemId(R.id.nav_friends); bottomNav.setSelectedItemId(R.id.nav_friends);
// 更新未读消息徽章
UnreadMessageManager.updateBadge(bottomNav); UnreadMessageManager.updateBadge(bottomNav);
loadPosts();
} }
} }
} }

View File

@ -29,6 +29,7 @@ import com.example.livestreaming.net.ApiClient;
import com.example.livestreaming.net.ApiResponse; import com.example.livestreaming.net.ApiResponse;
import com.example.livestreaming.net.ApiService; import com.example.livestreaming.net.ApiService;
import com.example.livestreaming.net.AuthStore; import com.example.livestreaming.net.AuthStore;
import com.example.livestreaming.net.ChatMessageResponse;
import com.example.livestreaming.net.CreateRechargeRequest; import com.example.livestreaming.net.CreateRechargeRequest;
import com.example.livestreaming.net.CreateRechargeResponse; import com.example.livestreaming.net.CreateRechargeResponse;
import com.example.livestreaming.net.GiftResponse; import com.example.livestreaming.net.GiftResponse;

View File

@ -152,37 +152,29 @@ public class SearchActivity extends AppCompatActivity {
Log.d(TAG, "执行搜索: " + keyword); Log.d(TAG, "执行搜索: " + keyword);
ApiService apiService = ApiClient.getService(this); ApiService apiService = ApiClient.getService(this);
Call<ApiResponse<PageResponse<Map<String, Object>>>> call = Call<ApiResponse<PageResponse<Room>>> call =
apiService.searchLiveRooms(keyword, null, null, 1, 20); apiService.searchLiveRooms(keyword, null, null, 1, 20);
call.enqueue(new Callback<ApiResponse<PageResponse<Map<String, Object>>>>() { call.enqueue(new Callback<ApiResponse<PageResponse<Room>>>() {
@Override @Override
public void onResponse(Call<ApiResponse<PageResponse<Map<String, Object>>>> call, public void onResponse(Call<ApiResponse<PageResponse<Room>>> call,
Response<ApiResponse<PageResponse<Map<String, Object>>>> response) { Response<ApiResponse<PageResponse<Room>>> response) {
isSearching = false; isSearching = false;
if (response.isSuccessful() && response.body() != null) { if (response.isSuccessful() && response.body() != null) {
ApiResponse<PageResponse<Map<String, Object>>> apiResponse = response.body(); ApiResponse<PageResponse<Room>> apiResponse = response.body();
if (apiResponse.getCode() == 200 && apiResponse.getData() != null) { if (apiResponse.getCode() == 200 && apiResponse.getData() != null) {
PageResponse<Map<String, Object>> pageResponse = apiResponse.getData(); PageResponse<Room> pageResponse = apiResponse.getData();
List<Map<String, Object>> rooms = pageResponse.getList(); List<Room> rooms = pageResponse.getList();
if (rooms != null && !rooms.isEmpty()) { if (rooms != null && !rooms.isEmpty()) {
List<Room> roomList = new ArrayList<>();
for (Map<String, Object> roomData : rooms) {
Room room = parseRoomFromMap(roomData);
if (room != null) {
roomList.add(room);
}
}
all.clear(); all.clear();
all.addAll(roomList); all.addAll(rooms);
adapter.submitList(new ArrayList<>(all)); adapter.submitList(new ArrayList<>(all));
updateEmptyState(all); updateEmptyState(all);
Log.d(TAG, "搜索成功,找到 " + roomList.size() + " 个直播间"); Log.d(TAG, "搜索成功,找到 " + rooms.size() + " 个直播间");
} else { } else {
all.clear(); all.clear();
adapter.submitList(new ArrayList<>()); adapter.submitList(new ArrayList<>());
@ -204,7 +196,7 @@ public class SearchActivity extends AppCompatActivity {
} }
@Override @Override
public void onFailure(Call<ApiResponse<PageResponse<Map<String, Object>>>> call, Throwable t) { public void onFailure(Call<ApiResponse<PageResponse<Room>>> call, Throwable t) {
isSearching = false; isSearching = false;
Toast.makeText(SearchActivity.this, Toast.makeText(SearchActivity.this,
"网络错误: " + t.getMessage(), "网络错误: " + t.getMessage(),

View File

@ -3,15 +3,21 @@ package com.example.livestreaming;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.view.View;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import com.example.livestreaming.databinding.ActivityTableGamesBinding; import com.example.livestreaming.databinding.ActivityTableGamesBinding;
import com.google.android.material.bottomnavigation.BottomNavigationView; import com.google.android.material.bottomnavigation.BottomNavigationView;
import java.util.List;
public class TableGamesActivity extends AppCompatActivity { public class TableGamesActivity extends AppCompatActivity {
private static final String CATEGORY = "桌子游戏";
private ActivityTableGamesBinding binding; private ActivityTableGamesBinding binding;
private PostAdapter postAdapter;
public static void start(Context context) { public static void start(Context context) {
Intent intent = new Intent(context, TableGamesActivity.class); Intent intent = new Intent(context, TableGamesActivity.class);
@ -25,15 +31,29 @@ public class TableGamesActivity extends AppCompatActivity {
setContentView(binding.getRoot()); setContentView(binding.getRoot());
setupUI(); setupUI();
setupRecyclerView();
loadPosts();
} }
private void setupUI() { private void setupUI() {
binding.backButton.setOnClickListener(v -> finish()); binding.backButton.setOnClickListener(v -> finish());
binding.fabPublish.setOnClickListener(v -> {
PublishPostHelper.showPublishDialog(this, CATEGORY, new PublishPostHelper.PublishCallback() {
@Override
public void onSuccess(Post post) {
postAdapter.addPost(post);
binding.recyclerPosts.scrollToPosition(0);
updateEmptyView();
}
@Override
public void onError(String error) {}
});
});
BottomNavigationView bottomNavigation = binding.bottomNavInclude.bottomNavigation; BottomNavigationView bottomNavigation = binding.bottomNavInclude.bottomNavigation;
bottomNavigation.setSelectedItemId(R.id.nav_friends); bottomNavigation.setSelectedItemId(R.id.nav_friends);
// 更新未读消息徽章
UnreadMessageManager.updateBadge(bottomNavigation); UnreadMessageManager.updateBadge(bottomNavigation);
bottomNavigation.setOnItemSelectedListener(item -> { bottomNavigation.setOnItemSelectedListener(item -> {
@ -62,15 +82,36 @@ public class TableGamesActivity extends AppCompatActivity {
}); });
} }
private void setupRecyclerView() {
postAdapter = new PostAdapter();
binding.recyclerPosts.setLayoutManager(new LinearLayoutManager(this));
binding.recyclerPosts.setAdapter(postAdapter);
}
private void loadPosts() {
List<Post> posts = PostManager.getPostsByCategory(this, CATEGORY);
postAdapter.setPosts(posts);
updateEmptyView();
}
private void updateEmptyView() {
if (postAdapter.getItemCount() == 0) {
binding.emptyView.setVisibility(View.VISIBLE);
binding.recyclerPosts.setVisibility(View.GONE);
} else {
binding.emptyView.setVisibility(View.GONE);
binding.recyclerPosts.setVisibility(View.VISIBLE);
}
}
@Override @Override
protected void onResume() { protected void onResume() {
super.onResume(); super.onResume();
if (binding != null) { if (binding != null) {
BottomNavigationView bottomNav = binding.bottomNavInclude.bottomNavigation; BottomNavigationView bottomNav = binding.bottomNavInclude.bottomNavigation;
bottomNav.setSelectedItemId(R.id.nav_friends); bottomNav.setSelectedItemId(R.id.nav_friends);
// 更新未读消息徽章
UnreadMessageManager.updateBadge(bottomNav); UnreadMessageManager.updateBadge(bottomNav);
loadPosts();
} }
} }
} }

View File

@ -1,11 +1,19 @@
package com.example.livestreaming; package com.example.livestreaming;
import android.app.Dialog;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.os.Looper; import android.os.Looper;
import android.view.View;
import android.view.Window;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import com.example.livestreaming.databinding.ActivityWishTreeBinding; import com.example.livestreaming.databinding.ActivityWishTreeBinding;
@ -20,101 +28,149 @@ import java.util.TimeZone;
public class WishTreeActivity extends AppCompatActivity { public class WishTreeActivity extends AppCompatActivity {
private ActivityWishTreeBinding binding; private ActivityWishTreeBinding binding;
private final Handler handler = new Handler(Looper.getMainLooper()); private final Handler handler = new Handler(Looper.getMainLooper());
private Runnable timerRunnable; private Runnable timerRunnable;
private SharedPreferences prefs;
private String[] wishes = new String[7];
public static void start(Context context) { public static void start(Context context) {
Intent intent = new Intent(context, WishTreeActivity.class); context.startActivity(new Intent(context, WishTreeActivity.class));
context.startActivity(intent);
}
@Override
protected void onStart() {
super.onStart();
startBannerCountdown();
}
@Override
protected void onStop() {
super.onStop();
stopBannerCountdown();
}
private void startBannerCountdown() {
stopBannerCountdown();
timerRunnable = new Runnable() {
@Override
public void run() {
updateBannerTimer();
handler.postDelayed(this, 1000);
}
};
handler.post(timerRunnable);
}
private void stopBannerCountdown() {
if (timerRunnable != null) {
handler.removeCallbacks(timerRunnable);
timerRunnable = null;
}
}
private void updateBannerTimer() {
if (binding == null) return;
try {
long now = System.currentTimeMillis();
TimeZone tz = TimeZone.getDefault();
Calendar c = Calendar.getInstance(tz);
c.setTimeInMillis(now);
c.set(Calendar.HOUR_OF_DAY, 0);
c.set(Calendar.MINUTE, 0);
c.set(Calendar.SECOND, 0);
c.set(Calendar.MILLISECOND, 0);
c.add(Calendar.DAY_OF_MONTH, 1);
long nextMidnight = c.getTimeInMillis();
long diff = Math.max(0, nextMidnight - now);
long totalSeconds = diff / 1000;
long hours = totalSeconds / 3600;
long minutes = (totalSeconds % 3600) / 60;
long seconds = totalSeconds % 60;
SimpleDateFormat fmt = new SimpleDateFormat("HH:mm:ss", Locale.getDefault());
fmt.setTimeZone(tz);
String current = fmt.format(new Date(now));
String remain = String.format(Locale.getDefault(), "%02d:%02d:%02d", hours, minutes, seconds);
binding.bannerTimer.setText(current + " " + remain);
} catch (Exception ignored) {
}
} }
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
// TODO: 接入后端接口 - 获取愿望树相关数据
// 接口路径: GET /api/wish_tree/info
// 请求参数:
// - userId: 当前用户ID从token中获取可选
// 返回数据格式: ApiResponse<WishTreeInfo>
// WishTreeInfo对象应包含: totalWishes, todayWishes, userWishCount, nextResetTime等字段
// 用于显示愿望树统计信息和倒计时
binding = ActivityWishTreeBinding.inflate(getLayoutInflater()); binding = ActivityWishTreeBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot()); setContentView(binding.getRoot());
prefs = getSharedPreferences("wishes", MODE_PRIVATE);
loadWishes();
startBannerCountdown(); startBannerCountdown();
setupBottomNav();
setupWishCards();
setupMakeWishButton();
}
BottomNavigationView bottomNavigation = binding.bottomNavInclude.bottomNavigation; private void loadWishes() {
bottomNavigation.setSelectedItemId(R.id.nav_wish_tree); for (int i = 0; i < 7; i++) {
wishes[i] = prefs.getString("wish_" + i, "");
}
updateWishCards();
}
// 更新未读消息徽章 private void saveWish(int index, String wish) {
UnreadMessageManager.updateBadge(bottomNavigation); wishes[index] = wish;
prefs.edit().putString("wish_" + index, wish).apply();
updateWishCards();
}
bottomNavigation.setOnItemSelectedListener(item -> { private void updateWishCards() {
int id = item.getItemId(); TextView[] cards = {
if (id == R.id.nav_wish_tree) { binding.wishCard1, binding.wishCard2, binding.wishCard3,
return true; binding.wishCard4, binding.wishCard5, binding.wishCard6, binding.wishCard7
};
for (int i = 0; i < cards.length; i++) {
if (wishes[i] != null && !wishes[i].isEmpty()) {
String text = wishes[i].length() > 8 ? wishes[i].substring(0, 8) + "..." : wishes[i];
cards[i].setText(text);
} else {
cards[i].setText("");
} }
}
}
private void setupWishCards() {
TextView[] cards = {
binding.wishCard1, binding.wishCard2, binding.wishCard3,
binding.wishCard4, binding.wishCard5, binding.wishCard6, binding.wishCard7
};
for (int i = 0; i < cards.length; i++) {
final int index = i;
cards[i].setOnClickListener(v -> onWishCardClick(index));
}
binding.addWishCard.setOnClickListener(v -> showMakeWishConfirmDialog(-1));
}
private void onWishCardClick(int index) {
if (wishes[index] != null && !wishes[index].isEmpty()) {
showViewWishDialog(index);
} else {
showMakeWishConfirmDialog(index);
}
}
private void showMakeWishConfirmDialog(int index) {
new AlertDialog.Builder(this)
.setTitle("许愿确认")
.setMessage("是否要在这里许下心愿?")
.setNegativeButton("取消", null)
.setPositiveButton("进行许愿", (d, w) -> showMakeWishInputDialog(index))
.show();
}
private void showMakeWishInputDialog(int index) {
View view = getLayoutInflater().inflate(R.layout.dialog_make_wish, null);
EditText input = view.findViewById(R.id.editWish);
new AlertDialog.Builder(this)
.setTitle("写下你的心愿")
.setView(view)
.setNegativeButton("取消", null)
.setPositiveButton("确认", (d, w) -> {
String wish = input.getText().toString().trim();
if (!wish.isEmpty()) {
int saveIndex = index >= 0 ? index : findEmptySlot();
if (saveIndex >= 0) {
saveWish(saveIndex, wish);
showSuccessDialog();
} else {
Toast.makeText(this, "心愿牌已满", Toast.LENGTH_SHORT).show();
}
}
})
.show();
}
private int findEmptySlot() {
for (int i = 0; i < wishes.length; i++) {
if (wishes[i] == null || wishes[i].isEmpty()) return i;
}
return -1;
}
private void showSuccessDialog() {
Dialog dialog = new Dialog(this);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(R.layout.dialog_wish_success);
dialog.show();
handler.postDelayed(dialog::dismiss, 1500);
}
private void showViewWishDialog(int index) {
new AlertDialog.Builder(this)
.setTitle("我的心愿")
.setMessage(wishes[index])
.setPositiveButton("关闭", null)
.setNegativeButton("删除心愿", (d, w) -> {
saveWish(index, "");
Toast.makeText(this, "心愿已删除", Toast.LENGTH_SHORT).show();
})
.show();
}
private void setupMakeWishButton() {
binding.btnMakeWish.setOnClickListener(v -> showMakeWishConfirmDialog(-1));
}
private void setupBottomNav() {
BottomNavigationView bottomNav = binding.bottomNavInclude.bottomNavigation;
bottomNav.setSelectedItemId(R.id.nav_wish_tree);
UnreadMessageManager.updateBadge(bottomNav);
bottomNav.setOnItemSelectedListener(item -> {
int id = item.getItemId();
if (id == R.id.nav_wish_tree) return true;
if (id == R.id.nav_home) { if (id == R.id.nav_home) {
startActivity(new Intent(this, MainActivity.class)); startActivity(new Intent(this, MainActivity.class));
finish(); finish();
@ -139,14 +195,62 @@ public class WishTreeActivity extends AppCompatActivity {
}); });
} }
@Override
protected void onStart() {
super.onStart();
startBannerCountdown();
}
@Override
protected void onStop() {
super.onStop();
stopBannerCountdown();
}
private void startBannerCountdown() {
stopBannerCountdown();
timerRunnable = () -> {
updateBannerTimer();
handler.postDelayed(timerRunnable, 1000);
};
handler.post(timerRunnable);
}
private void stopBannerCountdown() {
if (timerRunnable != null) {
handler.removeCallbacks(timerRunnable);
timerRunnable = null;
}
}
private void updateBannerTimer() {
if (binding == null) return;
try {
long now = System.currentTimeMillis();
TimeZone tz = TimeZone.getDefault();
Calendar c = Calendar.getInstance(tz);
c.setTimeInMillis(now);
c.set(Calendar.HOUR_OF_DAY, 0);
c.set(Calendar.MINUTE, 0);
c.set(Calendar.SECOND, 0);
c.set(Calendar.MILLISECOND, 0);
c.add(Calendar.DAY_OF_MONTH, 1);
long diff = Math.max(0, c.getTimeInMillis() - now);
long h = diff / 3600000;
long m = (diff % 3600000) / 60000;
long s = (diff % 60000) / 1000;
SimpleDateFormat fmt = new SimpleDateFormat("HH:mm:ss", Locale.getDefault());
fmt.setTimeZone(tz);
binding.bannerTimer.setText(fmt.format(new Date(now)) + " " + String.format(Locale.getDefault(), "%02d:%02d:%02d", h, m, s));
} catch (Exception ignored) {}
}
@Override @Override
protected void onResume() { protected void onResume() {
super.onResume(); super.onResume();
if (binding != null) { if (binding != null) {
BottomNavigationView bottomNav = binding.bottomNavInclude.bottomNavigation; binding.bottomNavInclude.bottomNavigation.setSelectedItemId(R.id.nav_wish_tree);
bottomNav.setSelectedItemId(R.id.nav_wish_tree); UnreadMessageManager.updateBadge(binding.bottomNavInclude.bottomNavigation);
// 更新未读消息徽章
UnreadMessageManager.updateBadge(bottomNav);
} }
} }
} }

View File

@ -265,4 +265,126 @@ public interface ApiService {
Call<ApiResponse<Boolean>> transferGroup( Call<ApiResponse<Boolean>> transferGroup(
@Path("groupId") long groupId, @Path("groupId") long groupId,
@Body TransferGroupRequest body); @Body TransferGroupRequest body);
// ==================== 分类接口 ====================
@GET("api/front/category/live")
Call<ApiResponse<List<CategoryResponse>>> getLiveRoomCategories();
@GET("api/front/category/work")
Call<ApiResponse<List<CategoryResponse>>> getWorkCategories();
@GET("api/front/category/list")
Call<ApiResponse<List<CategoryResponse>>> getCategories(@Query("type") int type);
@GET("api/front/category/hot")
Call<ApiResponse<List<CategoryResponse>>> getHotCategories(
@Query("type") int type,
@Query("limit") int limit);
@GET("api/front/category/statistics")
Call<ApiResponse<Map<String, Object>>> getCategoryStatistics(@Query("type") int type);
// ==================== 关注接口 ====================
@GET("api/front/follow/followers")
Call<ApiResponse<PageResponse<Map<String, Object>>>> getFollowersList(
@Query("page") int page,
@Query("pageSize") int pageSize);
@GET("api/front/follow/following")
Call<ApiResponse<PageResponse<Map<String, Object>>>> getFollowingList(
@Query("page") int page,
@Query("pageSize") int pageSize);
@GET("api/front/follow/stats")
Call<ApiResponse<Map<String, Object>>> getFollowStats(@Query("userId") Integer userId);
@GET("api/front/follow/check/{userId}")
Call<ApiResponse<Map<String, Object>>> checkFollowStatus(@Path("userId") int userId);
@POST("api/front/follow")
Call<ApiResponse<Map<String, Object>>> followUser(@Body Map<String, Object> body);
@POST("api/front/follow/cancel")
Call<ApiResponse<Map<String, Object>>> unfollowUser(@Body Map<String, Object> body);
// ==================== 作品接口 ====================
@Multipart
@POST("api/front/upload/video")
Call<ApiResponse<FileUploadResponse>> uploadVideo(
@Part MultipartBody.Part file,
@Part("model") RequestBody model,
@Part("pid") RequestBody pid);
@POST("api/front/works/publish")
Call<ApiResponse<Long>> publishWork(@Body WorksRequest body);
@GET("api/front/works/{id}")
Call<ApiResponse<WorksResponse>> getWorkDetail(@Path("id") long id);
@DELETE("api/front/works/{id}")
Call<ApiResponse<Boolean>> deleteWork(@Path("id") long id);
@POST("api/front/works/{id}/like")
Call<ApiResponse<Boolean>> likeWork(@Path("id") long id);
@DELETE("api/front/works/{id}/like")
Call<ApiResponse<Boolean>> unlikeWork(@Path("id") long id);
@POST("api/front/works/{id}/collect")
Call<ApiResponse<Boolean>> collectWork(@Path("id") long id);
@DELETE("api/front/works/{id}/collect")
Call<ApiResponse<Boolean>> uncollectWork(@Path("id") long id);
// ==================== 搜索接口 ====================
@GET("api/front/live/public/rooms/search")
Call<ApiResponse<PageResponse<Room>>> searchLiveRooms(
@Query("keyword") String keyword,
@Query("categoryId") Integer categoryId,
@Query("status") Integer status,
@Query("page") int page,
@Query("pageSize") int pageSize);
@GET("api/front/search/hot")
Call<ApiResponse<List<HotSearchResponse>>> getHotSearch(
@Query("type") int type,
@Query("limit") int limit);
@GET("api/front/search/suggestions")
Call<ApiResponse<List<String>>> getSearchSuggestions(
@Query("keyword") String keyword,
@Query("type") int type,
@Query("limit") int limit);
// ==================== 观看历史 ====================
@POST("api/front/history/watch")
Call<ApiResponse<Map<String, Object>>> recordWatchHistory(@Body Map<String, Object> body);
// ==================== 支付接口 ====================
@POST("api/front/pay/payment")
Call<ApiResponse<OrderPayResultResponse>> payment(@Body OrderPayRequest body);
// ==================== 直播间礼物 ====================
@POST("api/front/live/rooms/{roomId}/gift")
Call<ApiResponse<SendGiftResponse>> sendRoomGift(
@Path("roomId") String roomId,
@Body SendGiftRequest body);
// ==================== 直播控制 ====================
@POST("api/front/live/rooms/{roomId}/start")
Call<ApiResponse<Map<String, Object>>> startLiveRoom(@Path("roomId") String roomId);
@POST("api/front/live/rooms/{roomId}/stop")
Call<ApiResponse<Map<String, Object>>> stopLiveRoom(@Path("roomId") String roomId);
@POST("api/front/live/rooms/{roomId}/broadcast/online")
Call<ApiResponse<Map<String, Object>>> broadcastOnlineCount(@Path("roomId") String roomId);
} }

View File

@ -3,7 +3,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="#FFFFFF"> android:background="#F5F5F5">
<ImageView <ImageView
android:id="@+id/backButton" android:id="@+id/backButton"
@ -30,11 +30,12 @@
app:layout_constraintTop_toBottomOf="@id/backButton" /> app:layout_constraintTop_toBottomOf="@id/backButton" />
<TextView <TextView
android:id="@+id/subtitleText"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="32dp" android:layout_marginStart="32dp"
android:layout_marginEnd="32dp" android:layout_marginEnd="32dp"
android:layout_marginTop="32dp" android:layout_marginTop="8dp"
android:gravity="center" android:gravity="center"
android:text="发挥你的想象力,画出你的创意" android:text="发挥你的想象力,画出你的创意"
android:textColor="#666666" android:textColor="#666666"
@ -43,6 +44,61 @@
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/titleText" /> app:layout_constraintTop_toBottomOf="@id/titleText" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerPosts"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="16dp"
android:clipToPadding="false"
android:paddingBottom="70dp"
app:layout_constraintBottom_toTopOf="@id/bottomNavInclude"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/subtitleText" />
<LinearLayout
android:id="@+id/emptyView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical"
android:visibility="gone"
app:layout_constraintBottom_toTopOf="@id/bottomNavInclude"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/subtitleText">
<ImageView
android:layout_width="80dp"
android:layout_height="80dp"
android:alpha="0.5"
android:src="@drawable/ic_chat_24" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="还没有动态,快来发布第一条吧~"
android:textColor="#999999"
android:textSize="14sp" />
</LinearLayout>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fabPublish"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:layout_marginBottom="80dp"
android:contentDescription="发布动态"
android:src="@drawable/ic_add_24"
app:backgroundTint="#9C27B0"
app:tint="#FFFFFF"
app:fabSize="normal"
app:elevation="6dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<include <include
android:id="@+id/bottomNavInclude" android:id="@+id/bottomNavInclude"
layout="@layout/include_bottom_nav" layout="@layout/include_bottom_nav"
@ -53,4 +109,3 @@
app:layout_constraintStart_toStartOf="parent" /> app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -3,7 +3,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="#FFFFFF"> android:background="#F5F5F5">
<ImageView <ImageView
android:id="@+id/backButton" android:id="@+id/backButton"
@ -30,11 +30,12 @@
app:layout_constraintTop_toBottomOf="@id/backButton" /> app:layout_constraintTop_toBottomOf="@id/backButton" />
<TextView <TextView
android:id="@+id/subtitleText"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="32dp" android:layout_marginStart="32dp"
android:layout_marginEnd="32dp" android:layout_marginEnd="32dp"
android:layout_marginTop="32dp" android:layout_marginTop="8dp"
android:gravity="center" android:gravity="center"
android:text="找到志同道合的游戏伙伴,一起开黑" android:text="找到志同道合的游戏伙伴,一起开黑"
android:textColor="#666666" android:textColor="#666666"
@ -43,6 +44,61 @@
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/titleText" /> app:layout_constraintTop_toBottomOf="@id/titleText" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerPosts"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="16dp"
android:clipToPadding="false"
android:paddingBottom="70dp"
app:layout_constraintBottom_toTopOf="@id/bottomNavInclude"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/subtitleText" />
<LinearLayout
android:id="@+id/emptyView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical"
android:visibility="gone"
app:layout_constraintBottom_toTopOf="@id/bottomNavInclude"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/subtitleText">
<ImageView
android:layout_width="80dp"
android:layout_height="80dp"
android:alpha="0.5"
android:src="@drawable/ic_chat_24" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="还没有动态,快来发布第一条吧~"
android:textColor="#999999"
android:textSize="14sp" />
</LinearLayout>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fabPublish"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:layout_marginBottom="80dp"
android:contentDescription="发布动态"
android:src="@drawable/ic_add_24"
app:backgroundTint="#9C27B0"
app:tint="#FFFFFF"
app:fabSize="normal"
app:elevation="6dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<include <include
android:id="@+id/bottomNavInclude" android:id="@+id/bottomNavInclude"
layout="@layout/include_bottom_nav" layout="@layout/include_bottom_nav"
@ -53,4 +109,3 @@
app:layout_constraintStart_toStartOf="parent" /> app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -3,7 +3,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="#FFFFFF"> android:background="#F5F5F5">
<ImageView <ImageView
android:id="@+id/backButton" android:id="@+id/backButton"
@ -30,11 +30,12 @@
app:layout_constraintTop_toBottomOf="@id/backButton" /> app:layout_constraintTop_toBottomOf="@id/backButton" />
<TextView <TextView
android:id="@+id/subtitleText"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="32dp" android:layout_marginStart="32dp"
android:layout_marginEnd="32dp" android:layout_marginEnd="32dp"
android:layout_marginTop="32dp" android:layout_marginTop="8dp"
android:gravity="center" android:gravity="center"
android:text="和好友一起K歌享受音乐时光" android:text="和好友一起K歌享受音乐时光"
android:textColor="#666666" android:textColor="#666666"
@ -43,6 +44,61 @@
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/titleText" /> app:layout_constraintTop_toBottomOf="@id/titleText" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerPosts"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="16dp"
android:clipToPadding="false"
android:paddingBottom="70dp"
app:layout_constraintBottom_toTopOf="@id/bottomNavInclude"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/subtitleText" />
<LinearLayout
android:id="@+id/emptyView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical"
android:visibility="gone"
app:layout_constraintBottom_toTopOf="@id/bottomNavInclude"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/subtitleText">
<ImageView
android:layout_width="80dp"
android:layout_height="80dp"
android:alpha="0.5"
android:src="@drawable/ic_chat_24" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="还没有动态,快来发布第一条吧~"
android:textColor="#999999"
android:textSize="14sp" />
</LinearLayout>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fabPublish"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:layout_marginBottom="80dp"
android:contentDescription="发布动态"
android:src="@drawable/ic_add_24"
app:backgroundTint="#9C27B0"
app:tint="#FFFFFF"
app:fabSize="normal"
app:elevation="6dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<include <include
android:id="@+id/bottomNavInclude" android:id="@+id/bottomNavInclude"
layout="@layout/include_bottom_nav" layout="@layout/include_bottom_nav"
@ -53,4 +109,3 @@
app:layout_constraintStart_toStartOf="parent" /> app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -3,7 +3,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="#FFFFFF"> android:background="#F5F5F5">
<ImageView <ImageView
android:id="@+id/backButton" android:id="@+id/backButton"
@ -30,11 +30,12 @@
app:layout_constraintTop_toBottomOf="@id/backButton" /> app:layout_constraintTop_toBottomOf="@id/backButton" />
<TextView <TextView
android:id="@+id/subtitleText"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="32dp" android:layout_marginStart="32dp"
android:layout_marginEnd="32dp" android:layout_marginEnd="32dp"
android:layout_marginTop="32dp" android:layout_marginTop="8dp"
android:gravity="center" android:gravity="center"
android:text="寻找你的另一半,开启一段美好的缘分" android:text="寻找你的另一半,开启一段美好的缘分"
android:textColor="#666666" android:textColor="#666666"
@ -43,6 +44,64 @@
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/titleText" /> app:layout_constraintTop_toBottomOf="@id/titleText" />
<!-- 动态列表 -->
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerPosts"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="16dp"
android:clipToPadding="false"
android:paddingBottom="70dp"
app:layout_constraintBottom_toTopOf="@id/bottomNavInclude"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/subtitleText" />
<!-- 空状态提示 -->
<LinearLayout
android:id="@+id/emptyView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical"
android:visibility="gone"
app:layout_constraintBottom_toTopOf="@id/bottomNavInclude"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/subtitleText">
<ImageView
android:layout_width="80dp"
android:layout_height="80dp"
android:alpha="0.5"
android:src="@drawable/ic_chat_24" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="还没有动态,快来发布第一条吧~"
android:textColor="#999999"
android:textSize="14sp" />
</LinearLayout>
<!-- 发布动态按钮 -->
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fabPublish"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:layout_marginBottom="80dp"
android:contentDescription="发布动态"
android:src="@drawable/ic_add_24"
app:backgroundTint="#9C27B0"
app:tint="#FFFFFF"
app:fabSize="normal"
app:elevation="6dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<include <include
android:id="@+id/bottomNavInclude" android:id="@+id/bottomNavInclude"
layout="@layout/include_bottom_nav" layout="@layout/include_bottom_nav"
@ -53,4 +112,3 @@
app:layout_constraintStart_toStartOf="parent" /> app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -3,7 +3,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="#FFFFFF"> android:background="#F5F5F5">
<ImageView <ImageView
android:id="@+id/backButton" android:id="@+id/backButton"
@ -30,11 +30,12 @@
app:layout_constraintTop_toBottomOf="@id/backButton" /> app:layout_constraintTop_toBottomOf="@id/backButton" />
<TextView <TextView
android:id="@+id/subtitleText"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="32dp" android:layout_marginStart="32dp"
android:layout_marginEnd="32dp" android:layout_marginEnd="32dp"
android:layout_marginTop="32dp" android:layout_marginTop="8dp"
android:gravity="center" android:gravity="center"
android:text="组队开黑,一起吃鸡" android:text="组队开黑,一起吃鸡"
android:textColor="#666666" android:textColor="#666666"
@ -43,6 +44,61 @@
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/titleText" /> app:layout_constraintTop_toBottomOf="@id/titleText" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerPosts"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="16dp"
android:clipToPadding="false"
android:paddingBottom="70dp"
app:layout_constraintBottom_toTopOf="@id/bottomNavInclude"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/subtitleText" />
<LinearLayout
android:id="@+id/emptyView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical"
android:visibility="gone"
app:layout_constraintBottom_toTopOf="@id/bottomNavInclude"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/subtitleText">
<ImageView
android:layout_width="80dp"
android:layout_height="80dp"
android:alpha="0.5"
android:src="@drawable/ic_chat_24" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="还没有动态,快来发布第一条吧~"
android:textColor="#999999"
android:textSize="14sp" />
</LinearLayout>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fabPublish"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:layout_marginBottom="80dp"
android:contentDescription="发布动态"
android:src="@drawable/ic_add_24"
app:backgroundTint="#9C27B0"
app:tint="#FFFFFF"
app:fabSize="normal"
app:elevation="6dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<include <include
android:id="@+id/bottomNavInclude" android:id="@+id/bottomNavInclude"
layout="@layout/include_bottom_nav" layout="@layout/include_bottom_nav"
@ -53,4 +109,3 @@
app:layout_constraintStart_toStartOf="parent" /> app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -3,7 +3,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="#FFFFFF"> android:background="#F5F5F5">
<ImageView <ImageView
android:id="@+id/backButton" android:id="@+id/backButton"
@ -21,7 +21,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
android:text="桌子游" android:text="桌子游"
android:textColor="#111111" android:textColor="#111111"
android:textSize="20sp" android:textSize="20sp"
android:textStyle="bold" android:textStyle="bold"
@ -30,11 +30,12 @@
app:layout_constraintTop_toBottomOf="@id/backButton" /> app:layout_constraintTop_toBottomOf="@id/backButton" />
<TextView <TextView
android:id="@+id/subtitleText"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="32dp" android:layout_marginStart="32dp"
android:layout_marginEnd="32dp" android:layout_marginEnd="32dp"
android:layout_marginTop="32dp" android:layout_marginTop="8dp"
android:gravity="center" android:gravity="center"
android:text="经典桌游,欢乐无限" android:text="经典桌游,欢乐无限"
android:textColor="#666666" android:textColor="#666666"
@ -43,6 +44,61 @@
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/titleText" /> app:layout_constraintTop_toBottomOf="@id/titleText" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerPosts"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="16dp"
android:clipToPadding="false"
android:paddingBottom="70dp"
app:layout_constraintBottom_toTopOf="@id/bottomNavInclude"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/subtitleText" />
<LinearLayout
android:id="@+id/emptyView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical"
android:visibility="gone"
app:layout_constraintBottom_toTopOf="@id/bottomNavInclude"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/subtitleText">
<ImageView
android:layout_width="80dp"
android:layout_height="80dp"
android:alpha="0.5"
android:src="@drawable/ic_chat_24" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="还没有动态,快来发布第一条吧~"
android:textColor="#999999"
android:textSize="14sp" />
</LinearLayout>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fabPublish"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:layout_marginBottom="80dp"
android:contentDescription="发布动态"
android:src="@drawable/ic_add_24"
app:backgroundTint="#9C27B0"
app:tint="#FFFFFF"
app:fabSize="normal"
app:elevation="6dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<include <include
android:id="@+id/bottomNavInclude" android:id="@+id/bottomNavInclude"
layout="@layout/include_bottom_nav" layout="@layout/include_bottom_nav"
@ -53,4 +109,3 @@
app:layout_constraintStart_toStartOf="parent" /> app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -3,15 +3,15 @@
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="@android:color/white"> android:background="#1A0A1E">
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/content" android:id="@+id/content"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="#FFF7F7" android:paddingBottom="60dp">
android:paddingBottom="88dp">
<!-- 顶部栏 -->
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/topBar" android:id="@+id/topBar"
android:layout_width="0dp" android:layout_width="0dp"
@ -46,7 +46,8 @@
android:src="@drawable/ic_search_24" android:src="@drawable/ic_search_24"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/notifyButton" app:layout_constraintEnd_toStartOf="@id/notifyButton"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent"
app:tint="#FFFFFF" />
<ImageButton <ImageButton
android:id="@+id/notifyButton" android:id="@+id/notifyButton"
@ -58,10 +59,12 @@
android:src="@drawable/ic_notifications_24" android:src="@drawable/ic_notifications_24"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent"
app:tint="#FFFFFF" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
<!-- 活动横幅 -->
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/banner" android:id="@+id/banner"
android:layout_width="0dp" android:layout_width="0dp"
@ -105,21 +108,230 @@
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
<!-- 许愿树背景图 -->
<ImageView <ImageView
android:id="@+id/wishTreeImage" android:id="@+id/wishTreeImage"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="0dp"
android:layout_marginTop="12dp" android:clickable="false"
android:layout_marginStart="0dp" android:focusable="false"
android:layout_marginEnd="0dp"
android:adjustViewBounds="true"
android:contentDescription="Wish Tree" android:contentDescription="Wish Tree"
android:scaleType="fitCenter" android:scaleType="centerCrop"
android:src="@drawable/wish_tree" android:src="@drawable/wish_tree"
app:layout_constraintBottom_toTopOf="@id/bottomArea"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/banner" /> app:layout_constraintTop_toBottomOf="@id/banner" />
<!-- 心愿卡片1 -->
<TextView
android:id="@+id/wishCard1"
android:layout_width="50dp"
android:layout_height="65dp"
android:layout_marginStart="32dp"
android:layout_marginTop="80dp"
android:background="@drawable/bg_wish_card"
android:clickable="true"
android:focusable="true"
android:elevation="4dp"
android:gravity="center"
android:padding="4dp"
android:text=""
android:textColor="#5D4037"
android:textSize="8sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/banner" />
<!-- 心愿卡片2 -->
<TextView
android:id="@+id/wishCard2"
android:layout_width="58dp"
android:layout_height="75dp"
android:layout_marginStart="95dp"
android:layout_marginTop="55dp"
android:background="@drawable/bg_wish_card"
android:clickable="true"
android:focusable="true"
android:elevation="4dp"
android:gravity="center"
android:padding="5dp"
android:text=""
android:textColor="#5D4037"
android:textSize="9sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/banner" />
<!-- 心愿卡片3 -->
<TextView
android:id="@+id/wishCard3"
android:layout_width="50dp"
android:layout_height="65dp"
android:layout_marginEnd="35dp"
android:layout_marginTop="65dp"
android:background="@drawable/bg_wish_card"
android:clickable="true"
android:focusable="true"
android:elevation="4dp"
android:gravity="center"
android:padding="4dp"
android:text=""
android:textColor="#5D4037"
android:textSize="8sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/banner" />
<!-- 心愿卡片4 -->
<TextView
android:id="@+id/wishCard4"
android:layout_width="58dp"
android:layout_height="75dp"
android:layout_marginStart="18dp"
android:layout_marginTop="155dp"
android:background="@drawable/bg_wish_card"
android:clickable="true"
android:focusable="true"
android:elevation="4dp"
android:gravity="center"
android:padding="5dp"
android:text=""
android:textColor="#5D4037"
android:textSize="9sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/banner" />
<!-- 添加心愿按钮 -->
<TextView
android:id="@+id/addWishCard"
android:layout_width="62dp"
android:layout_height="80dp"
android:layout_marginEnd="75dp"
android:layout_marginTop="130dp"
android:background="@drawable/bg_wish_card_add"
android:clickable="true"
android:focusable="true"
android:elevation="4dp"
android:gravity="center"
android:padding="5dp"
android:text="心愿\n+"
android:textColor="#FF6D00"
android:textSize="12sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/banner" />
<!-- 心愿卡片5 -->
<TextView
android:id="@+id/wishCard5"
android:layout_width="50dp"
android:layout_height="65dp"
android:layout_marginEnd="25dp"
android:layout_marginTop="160dp"
android:background="@drawable/bg_wish_card"
android:clickable="true"
android:focusable="true"
android:elevation="4dp"
android:gravity="center"
android:padding="4dp"
android:text=""
android:textColor="#5D4037"
android:textSize="8sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/banner" />
<!-- 心愿卡片6 -->
<TextView
android:id="@+id/wishCard6"
android:layout_width="58dp"
android:layout_height="75dp"
android:layout_marginStart="50dp"
android:layout_marginTop="230dp"
android:background="@drawable/bg_wish_card"
android:clickable="true"
android:focusable="true"
android:elevation="4dp"
android:gravity="center"
android:padding="5dp"
android:text=""
android:textColor="#5D4037"
android:textSize="9sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/banner" />
<!-- 心愿卡片7 -->
<TextView
android:id="@+id/wishCard7"
android:layout_width="50dp"
android:layout_height="65dp"
android:layout_marginEnd="55dp"
android:layout_marginTop="240dp"
android:background="@drawable/bg_wish_card"
android:clickable="true"
android:focusable="true"
android:elevation="4dp"
android:gravity="center"
android:padding="4dp"
android:text=""
android:textColor="#5D4037"
android:textSize="8sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/banner" />
<!-- 树干上的金色竖向文字 -->
<TextView
android:id="@+id/tvTrunkText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="100dp"
android:background="@drawable/bg_trunk_text"
android:gravity="center"
android:lineSpacingExtra="8dp"
android:paddingHorizontal="12dp"
android:paddingVertical="16dp"
android:text="元\n旦\n许\n愿\n树"
android:textColor="#FFD700"
android:textSize="18sp"
android:textStyle="bold"
android:shadowColor="#000000"
android:shadowDx="1"
android:shadowDy="1"
android:shadowRadius="2"
app:layout_constraintBottom_toTopOf="@id/bottomArea"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<!-- 底部区域 -->
<LinearLayout
android:id="@+id/bottomArea"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="#2D1B36"
android:gravity="center"
android:orientation="vertical"
android:paddingVertical="12dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
<TextView
android:id="@+id/tvWishCount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="祈愿值0/100"
android:textColor="#FFD54F"
android:textSize="14sp" />
<com.google.android.material.button.MaterialButton
android:id="@+id/btnMakeWish"
android:layout_width="200dp"
android:layout_height="48dp"
android:layout_marginTop="8dp"
android:backgroundTint="#FF6D00"
android:text="前往祈愿"
android:textColor="#FFFFFF"
android:textSize="16sp"
app:cornerRadius="24dp" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
<include <include