主题:许愿树界面

This commit is contained in:
xiao12feng8 2026-01-09 10:24:35 +08:00
parent 7b7ca4f405
commit acebb8fc3e
13 changed files with 779 additions and 522 deletions

View File

@ -633,7 +633,7 @@ public class MainActivity extends AppCompatActivity {
return true;
}
if (id == R.id.nav_wish_tree) {
WishTreeWebViewActivity.start(this);
WishTreeActivity.start(this);
finish();
return true;
}

View File

@ -0,0 +1,169 @@
package com.example.livestreaming;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.OvershootInterpolator;
/**
* 许愿牌动画工具类
* 实现心愿从底部飘到树上的动画效果
*/
public class WishTagAnimator {
/**
* 执行心愿飘到树上的动画
* @param wishTag 许愿牌View
* @param startX 起始X坐标
* @param startY 起始Y坐标
* @param targetX 目标X坐标
* @param targetY 目标Y坐标
* @param duration 动画时长毫秒
* @param onComplete 动画完成回调
*/
public static void animateWishToTree(View wishTag, float startX, float startY,
float targetX, float targetY, long duration,
Runnable onComplete) {
// 设置初始位置和状态
wishTag.setX(startX);
wishTag.setY(startY);
wishTag.setAlpha(0f);
wishTag.setScaleX(0.3f);
wishTag.setScaleY(0.3f);
wishTag.setRotation(0f);
wishTag.setVisibility(View.VISIBLE);
// 创建动画集合
AnimatorSet animatorSet = new AnimatorSet();
// X轴移动动画
ObjectAnimator moveX = ObjectAnimator.ofFloat(wishTag, "x", startX, targetX);
moveX.setDuration(duration);
moveX.setInterpolator(new DecelerateInterpolator(1.5f));
// Y轴移动动画带轻微弹跳
ObjectAnimator moveY = ObjectAnimator.ofFloat(wishTag, "y", startY, targetY);
moveY.setDuration(duration);
moveY.setInterpolator(new DecelerateInterpolator(2f));
// 淡入动画
ObjectAnimator fadeIn = ObjectAnimator.ofFloat(wishTag, "alpha", 0f, 1f);
fadeIn.setDuration(duration / 3);
// 缩放动画
ObjectAnimator scaleX = ObjectAnimator.ofFloat(wishTag, "scaleX", 0.3f, 1.1f, 1f);
scaleX.setDuration(duration);
scaleX.setInterpolator(new OvershootInterpolator(1.2f));
ObjectAnimator scaleY = ObjectAnimator.ofFloat(wishTag, "scaleY", 0.3f, 1.1f, 1f);
scaleY.setDuration(duration);
scaleY.setInterpolator(new OvershootInterpolator(1.2f));
// 轻微旋转摇摆动画
ObjectAnimator rotate = ObjectAnimator.ofFloat(wishTag, "rotation", 0f, -8f, 8f, -5f, 5f, -2f, 2f, 0f);
rotate.setDuration(duration + 500);
rotate.setInterpolator(new DecelerateInterpolator());
// 同时播放所有动画
animatorSet.playTogether(moveX, moveY, fadeIn, scaleX, scaleY, rotate);
// 动画完成后的回调
if (onComplete != null) {
animatorSet.addListener(new android.animation.AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(android.animation.Animator animation) {
// 添加持续的轻微摇摆效果
startSwingAnimation(wishTag);
onComplete.run();
}
});
}
animatorSet.start();
}
/**
* 简化版动画 - 从屏幕底部中央飘到目标位置
*/
public static void animateFromBottom(View wishTag, View parentView, float targetX, float targetY,
Runnable onComplete) {
float startX = parentView.getWidth() / 2f - wishTag.getWidth() / 2f;
float startY = parentView.getHeight();
animateWishToTree(wishTag, startX, startY, targetX, targetY, 1500, onComplete);
}
/**
* 持续的轻微摇摆动画模拟风吹效果
*/
public static void startSwingAnimation(View wishTag) {
ObjectAnimator swing = ObjectAnimator.ofFloat(wishTag, "rotation", -2f, 2f);
swing.setDuration(2000);
swing.setRepeatCount(ValueAnimator.INFINITE);
swing.setRepeatMode(ValueAnimator.REVERSE);
swing.setInterpolator(new AccelerateDecelerateInterpolator());
swing.start();
}
/**
* 心愿牌出现动画淡入+缩放
*/
public static void animateAppear(View wishTag, long delay) {
wishTag.setAlpha(0f);
wishTag.setScaleX(0.5f);
wishTag.setScaleY(0.5f);
wishTag.setVisibility(View.VISIBLE);
AnimatorSet animatorSet = new AnimatorSet();
ObjectAnimator fadeIn = ObjectAnimator.ofFloat(wishTag, "alpha", 0f, 1f);
fadeIn.setDuration(500);
ObjectAnimator scaleX = ObjectAnimator.ofFloat(wishTag, "scaleX", 0.5f, 1f);
scaleX.setDuration(500);
ObjectAnimator scaleY = ObjectAnimator.ofFloat(wishTag, "scaleY", 0.5f, 1f);
scaleY.setDuration(500);
animatorSet.playTogether(fadeIn, scaleX, scaleY);
animatorSet.setStartDelay(delay);
animatorSet.setInterpolator(new OvershootInterpolator(1.5f));
animatorSet.start();
// 出现后开始摇摆
wishTag.postDelayed(() -> startSwingAnimation(wishTag), delay + 500);
}
/**
* 心愿牌消失动画
*/
public static void animateDisappear(View wishTag, Runnable onComplete) {
AnimatorSet animatorSet = new AnimatorSet();
ObjectAnimator fadeOut = ObjectAnimator.ofFloat(wishTag, "alpha", 1f, 0f);
fadeOut.setDuration(300);
ObjectAnimator scaleX = ObjectAnimator.ofFloat(wishTag, "scaleX", 1f, 0.3f);
scaleX.setDuration(300);
ObjectAnimator scaleY = ObjectAnimator.ofFloat(wishTag, "scaleY", 1f, 0.3f);
scaleY.setDuration(300);
animatorSet.playTogether(fadeOut, scaleX, scaleY);
if (onComplete != null) {
animatorSet.addListener(new android.animation.AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(android.animation.Animator animation) {
wishTag.setVisibility(View.GONE);
onComplete.run();
}
});
}
animatorSet.start();
}
}

View File

@ -1,7 +1,6 @@
package com.example.livestreaming;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
@ -12,6 +11,7 @@ import android.os.Looper;
import android.view.View;
import android.view.Window;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
@ -43,7 +43,7 @@ import retrofit2.Response;
/**
* 许愿树页面
* 数据通过API实时同步到服务端
* 新版本心愿牌样式带飘动动画
*/
public class WishTreeActivity extends AppCompatActivity {
@ -52,12 +52,26 @@ public class WishTreeActivity extends AppCompatActivity {
private Runnable timerRunnable;
private ApiService apiService;
// 心愿数据从服务端获取
// 心愿数据
private List<WishtreeResponse.Wish> myWishes = new ArrayList<>();
// 当前节日
private WishtreeResponse.Festival currentFestival;
// 是否正在加载
private boolean isLoading = false;
// 心愿牌View数组
private TextView[] wishTags;
// 心愿牌背景资源不同颜色
private final int[] tagBackgrounds = {
R.drawable.bg_wish_tag_pink,
R.drawable.bg_wish_tag_green,
R.drawable.bg_wish_tag_gold,
R.drawable.bg_wish_tag_blue,
R.drawable.bg_wish_tag_purple,
R.drawable.bg_wish_tag_yellow,
R.drawable.bg_wish_tag_orange,
R.drawable.bg_wish_tag_green,
R.drawable.bg_wish_tag_blue,
R.drawable.bg_wish_tag_pink
};
public static void start(Context context) {
context.startActivity(new Intent(context, WishTreeActivity.class));
@ -71,39 +85,57 @@ public class WishTreeActivity extends AppCompatActivity {
apiService = ApiClient.getService(this);
// 打印当前API地址和登录状态
String baseUrl = com.example.livestreaming.net.ApiClient.getCurrentBaseUrl(this);
String token = AuthStore.getToken(this);
android.util.Log.d("WishTree", "API地址: " + baseUrl);
android.util.Log.d("WishTree", "Token: " + (token != null && !token.isEmpty() ? "已登录" : "未登录"));
initWishTags();
startBannerCountdown();
setupBottomNav();
setupWishCards();
setupMakeWishButton();
setupTopBarButtons();
setupWishTagClicks();
// 加载数据
loadCurrentFestival();
loadMyWishes();
}
/**
* 初始化心愿牌数组
*/
private void initWishTags() {
wishTags = new TextView[]{
findViewById(R.id.wishTag1),
findViewById(R.id.wishTag2),
findViewById(R.id.wishTag3),
findViewById(R.id.wishTag4),
findViewById(R.id.wishTag5),
findViewById(R.id.wishTag6),
findViewById(R.id.wishTag7),
findViewById(R.id.wishTag8),
findViewById(R.id.wishTag9),
findViewById(R.id.wishTag10)
};
}
/**
* 设置顶部栏按钮
*/
private void setupTopBarButtons() {
// 搜索按钮
binding.searchButton.setOnClickListener(v -> {
SearchActivity.start(this);
});
// 通知按钮
binding.notifyButton.setOnClickListener(v -> {
NotificationsActivity.start(this);
});
binding.searchButton.setOnClickListener(v -> SearchActivity.start(this));
binding.notifyButton.setOnClickListener(v -> NotificationsActivity.start(this));
}
/**
* 检查是否已登录
* 设置心愿牌点击事件
*/
private void setupWishTagClicks() {
for (int i = 0; i < wishTags.length; i++) {
final int index = i;
if (wishTags[i] != null) {
wishTags[i].setOnClickListener(v -> onWishTagClick(index));
}
}
}
/**
* 检查登录状态
*/
private boolean checkLogin() {
String token = AuthStore.getToken(this);
@ -141,7 +173,7 @@ public class WishTreeActivity extends AppCompatActivity {
*/
private void updateBannerText() {
if (currentFestival != null && binding != null) {
String text = currentFestival.name + "许愿树 | 许下心愿,愿望成真";
String text = "" + currentFestival.name + " | 许下心愿,愿望成真";
binding.bannerText.setText(text);
}
}
@ -150,92 +182,85 @@ public class WishTreeActivity extends AppCompatActivity {
* 从服务端加载我的心愿
*/
private void loadMyWishes() {
android.util.Log.d("WishTree", "开始加载我的心愿列表");
apiService.getMyWishes(1, 10).enqueue(new Callback<ApiResponse<WishtreeResponse.WishPage>>() {
@Override
public void onResponse(@NonNull Call<ApiResponse<WishtreeResponse.WishPage>> call,
@NonNull Response<ApiResponse<WishtreeResponse.WishPage>> response) {
android.util.Log.d("WishTree", "加载心愿响应: code=" + response.code());
if (response.isSuccessful() && response.body() != null) {
android.util.Log.d("WishTree", "响应body: code=" + response.body().getCode());
if (response.body().getData() != null) {
if (response.isSuccessful() && response.body() != null && response.body().getData() != null) {
myWishes = response.body().getData().list;
if (myWishes == null) myWishes = new ArrayList<>();
android.util.Log.d("WishTree", "加载到 " + myWishes.size() + " 条心愿");
updateWishCards();
updateWishTags(false);
updateWishCount();
} else {
android.util.Log.w("WishTree", "响应数据为空");
myWishes = new ArrayList<>();
updateWishCards();
updateWishTags(false);
updateWishCount();
}
} else {
android.util.Log.e("WishTree", "加载心愿失败: " + response.code());
try {
if (response.errorBody() != null) {
android.util.Log.e("WishTree", "错误响应: " + response.errorBody().string());
}
} catch (Exception e) {
android.util.Log.e("WishTree", "读取错误响应失败", e);
}
}
}
@Override
public void onFailure(@NonNull Call<ApiResponse<WishtreeResponse.WishPage>> call, @NonNull Throwable t) {
android.util.Log.e("WishTree", "加载心愿网络错误", t);
Toast.makeText(WishTreeActivity.this, "加载心愿失败", Toast.LENGTH_SHORT).show();
}
});
}
/**
* 更新心愿卡片显示
* 更新心愿牌显示
* @param animate 是否播放动画
*/
private void updateWishCards() {
TextView[] cards = {
binding.wishCard1, binding.wishCard2, binding.wishCard3,
binding.wishCard4, binding.wishCard5, binding.wishCard6, binding.wishCard7
};
for (int i = 0; i < cards.length; i++) {
private void updateWishTags(boolean animate) {
for (int i = 0; i < wishTags.length; i++) {
if (wishTags[i] == null) continue;
if (i < myWishes.size() && myWishes.get(i) != null) {
String content = myWishes.get(i).content;
String text = content.length() > 8 ? content.substring(0, 8) + "..." : content;
cards[i].setText(text);
// 竖向显示文字最多5个字
String verticalText = formatVerticalText(content, 5);
wishTags[i].setText(verticalText);
wishTags[i].setBackgroundResource(tagBackgrounds[i % tagBackgrounds.length]);
if (animate) {
WishTagAnimator.animateAppear(wishTags[i], i * 150L);
} else {
cards[i].setText("");
wishTags[i].setVisibility(View.VISIBLE);
wishTags[i].setAlpha(1f);
WishTagAnimator.startSwingAnimation(wishTags[i]);
}
} else {
wishTags[i].setVisibility(View.GONE);
}
}
}
/**
* 格式化文字为竖向显示
*/
private String formatVerticalText(String text, int maxChars) {
if (text == null || text.isEmpty()) return "";
// 心愿牌较小最多显示5个字
String trimmed = text.length() > maxChars ? text.substring(0, maxChars) : text;
StringBuilder sb = new StringBuilder();
for (int i = 0; i < trimmed.length(); i++) {
sb.append(trimmed.charAt(i));
if (i < trimmed.length() - 1) sb.append("\n");
}
return sb.toString();
}
/**
* 更新祈愿值显示
*/
private void updateWishCount() {
int count = myWishes != null ? myWishes.size() : 0;
binding.tvWishCount.setText("祈愿值:" + count + "/100");
binding.progressWish.setProgress(count);
}
/**
* 设置心愿卡片点击事件
* 心愿牌点击
*/
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 -> showMakeWishInputDialog());
}
/**
* 心愿卡片点击
*/
private void onWishCardClick(int index) {
private void onWishTagClick(int index) {
if (index < myWishes.size() && myWishes.get(index) != null) {
showViewWishDialog(index);
} else {
@ -243,11 +268,17 @@ public class WishTreeActivity extends AppCompatActivity {
}
}
/**
* 设置许愿按钮
*/
private void setupMakeWishButton() {
binding.btnMakeWish.setOnClickListener(v -> showMakeWishInputDialog());
}
/**
* 显示许愿输入对话框
*/
private void showMakeWishInputDialog() {
// 检查登录状态
if (!checkLogin()) return;
Dialog dialog = new Dialog(this);
@ -264,7 +295,6 @@ public class WishTreeActivity extends AppCompatActivity {
View btnCancel = dialog.findViewById(R.id.btnCancel);
View btnMakeWish = dialog.findViewById(R.id.btnMakeWish);
// 字数统计
input.addTextChangedListener(new android.text.TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
@ -298,7 +328,6 @@ public class WishTreeActivity extends AppCompatActivity {
* 发布心愿到服务端
*/
private void publishWish(String content, Dialog dialog) {
// 检查登录状态
String token = AuthStore.getToken(this);
if (token == null || token.isEmpty()) {
Toast.makeText(this, "请先登录", Toast.LENGTH_SHORT).show();
@ -309,54 +338,69 @@ public class WishTreeActivity extends AppCompatActivity {
Integer festivalId = currentFestival != null ? currentFestival.id : null;
WishtreeRequest.PublishWish request = new WishtreeRequest.PublishWish(festivalId, content, null);
android.util.Log.d("WishTree", "发布心愿请求: festivalId=" + festivalId + ", content=" + content);
apiService.publishWish(request).enqueue(new Callback<ApiResponse<WishtreeResponse.Wish>>() {
@Override
public void onResponse(@NonNull Call<ApiResponse<WishtreeResponse.Wish>> call,
@NonNull Response<ApiResponse<WishtreeResponse.Wish>> response) {
android.util.Log.d("WishTree", "发布心愿响应: code=" + response.code());
if (response.isSuccessful() && response.body() != null) {
android.util.Log.d("WishTree", "响应body: code=" + response.body().getCode() + ", msg=" + response.body().getMessage());
if (response.body().isOk()) {
if (response.isSuccessful() && response.body() != null && response.body().isOk()) {
dialog.dismiss();
// 添加新心愿到列表
WishtreeResponse.Wish newWish = response.body().getData();
if (newWish != null) {
myWishes.add(0, newWish);
// 播放飘动动画
animateNewWishTag(newWish);
updateWishCount();
showSuccessDialog();
loadMyWishes(); // 重新加载心愿列表
} else {
String msg = response.body().getMessage();
Toast.makeText(WishTreeActivity.this,
msg != null && !msg.isEmpty() ? msg : "发布失败",
Toast.LENGTH_SHORT).show();
}
} else {
// 尝试读取错误响应
String errorMsg = "发布失败";
try {
if (response.errorBody() != null) {
String errorBody = response.errorBody().string();
android.util.Log.e("WishTree", "错误响应: " + errorBody);
errorMsg = "发布失败: " + response.code();
}
} catch (Exception e) {
android.util.Log.e("WishTree", "读取错误响应失败", e);
}
Toast.makeText(WishTreeActivity.this, errorMsg, Toast.LENGTH_SHORT).show();
String msg = response.body() != null ? response.body().getMessage() : "发布失败";
Toast.makeText(WishTreeActivity.this, msg != null ? msg : "发布失败", Toast.LENGTH_SHORT).show();
}
}
@Override
public void onFailure(@NonNull Call<ApiResponse<WishtreeResponse.Wish>> call, @NonNull Throwable t) {
android.util.Log.e("WishTree", "发布心愿网络错误", t);
String errorMsg = "网络错误";
if (t instanceof java.net.UnknownHostException) {
errorMsg = "无法连接服务器,请检查网络";
} else if (t instanceof java.net.SocketTimeoutException) {
errorMsg = "连接超时,请重试";
} else if (t.getMessage() != null) {
errorMsg = "网络错误: " + t.getMessage();
Toast.makeText(WishTreeActivity.this, "网络错误", Toast.LENGTH_SHORT).show();
}
Toast.makeText(WishTreeActivity.this, errorMsg, Toast.LENGTH_SHORT).show();
});
}
/**
* 播放新心愿飘到树上的动画
*/
private void animateNewWishTag(WishtreeResponse.Wish wish) {
// 找到第一个可用的心愿牌位置
int targetIndex = Math.min(myWishes.size() - 1, wishTags.length - 1);
if (targetIndex < 0 || targetIndex >= wishTags.length) return;
TextView targetTag = wishTags[targetIndex];
if (targetTag == null) return;
// 设置心愿内容
String verticalText = formatVerticalText(wish.content, 5);
targetTag.setText(verticalText);
targetTag.setBackgroundResource(tagBackgrounds[targetIndex % tagBackgrounds.length]);
// 获取目标位置
FrameLayout container = findViewById(R.id.wishTagsContainer);
if (container == null) return;
// 计算目标位置
float targetX = targetTag.getX();
float targetY = targetTag.getY();
// 从屏幕底部中央开始
float startX = container.getWidth() / 2f - targetTag.getWidth() / 2f;
float startY = container.getHeight();
// 执行动画
WishTagAnimator.animateWishToTree(targetTag, startX, startY, targetX, targetY, 1500, () -> {
// 动画完成后更新其他心愿牌
updateWishTags(false);
});
}
@ -397,38 +441,27 @@ public class WishTreeActivity extends AppCompatActivity {
tvContent.setText(wish.content);
// 显示点赞数和评论数
TextView tvLikeCount = dialog.findViewById(R.id.tvLikeCount);
TextView tvCommentCount = dialog.findViewById(R.id.tvCommentCount);
if (tvLikeCount != null) {
tvLikeCount.setText("" + wish.likeCount);
}
if (tvCommentCount != null) {
tvCommentCount.setText("💬 " + wish.commentCount);
}
if (tvLikeCount != null) tvLikeCount.setText("" + wish.likeCount);
if (tvCommentCount != null) tvCommentCount.setText("💬 " + wish.commentCount);
btnClose.setOnClickListener(v -> dialog.dismiss());
// 删除心愿 - 添加确认对话框
btnDelete.setOnClickListener(v -> {
new AlertDialog.Builder(this)
.setTitle("确认删除")
.setMessage("确定要删除这个心愿吗?")
.setPositiveButton("删除", (d, w) -> {
deleteWish(wish.id, dialog, false);
})
.setPositiveButton("删除", (d, w) -> deleteWish(wish.id, dialog, index))
.setNegativeButton("取消", null)
.show();
});
// 愿望达成 - 添加确认对话框
btnComplete.setOnClickListener(v -> {
new AlertDialog.Builder(this)
.setTitle("愿望达成")
.setMessage("恭喜!确认愿望已经达成了吗?")
.setPositiveButton("确认", (d, w) -> {
deleteWish(wish.id, dialog, true);
})
.setPositiveButton("确认", (d, w) -> deleteWish(wish.id, dialog, index))
.setNegativeButton("取消", null)
.show();
});
@ -438,23 +471,25 @@ public class WishTreeActivity extends AppCompatActivity {
/**
* 删除心愿
* @param wishId 心愿ID
* @param dialog 对话框
* @param isComplete 是否是愿望达成
*/
private void deleteWish(long wishId, Dialog dialog, boolean isComplete) {
private void deleteWish(long wishId, Dialog dialog, int index) {
apiService.deleteMyWish(wishId).enqueue(new Callback<ApiResponse<String>>() {
@Override
public void onResponse(@NonNull Call<ApiResponse<String>> call,
@NonNull Response<ApiResponse<String>> response) {
if (response.isSuccessful() && response.body() != null && response.body().isOk()) {
dialog.dismiss();
if (isComplete) {
showCompleteSuccessDialog();
// 播放消失动画
if (index < wishTags.length && wishTags[index] != null) {
WishTagAnimator.animateDisappear(wishTags[index], () -> {
loadMyWishes();
});
} else {
Toast.makeText(WishTreeActivity.this, "心愿已删除", Toast.LENGTH_SHORT).show();
loadMyWishes();
}
loadMyWishes(); // 重新加载
Toast.makeText(WishTreeActivity.this, "心愿已删除", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(WishTreeActivity.this, "操作失败", Toast.LENGTH_SHORT).show();
}
@ -467,24 +502,6 @@ public class WishTreeActivity extends AppCompatActivity {
});
}
/**
* 显示愿望达成成功对话框
*/
private void showCompleteSuccessDialog() {
Dialog dialog = new Dialog(this);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(R.layout.dialog_wish_complete);
if (dialog.getWindow() != null) {
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
}
dialog.show();
handler.postDelayed(dialog::dismiss, 2000);
}
private void setupMakeWishButton() {
binding.btnMakeWish.setOnClickListener(v -> showMakeWishInputDialog());
}
private void setupBottomNav() {
BottomNavigationView bottomNav = binding.bottomNavInclude.bottomNavigation;
bottomNav.setSelectedItemId(R.id.nav_wish_tree);
@ -561,9 +578,7 @@ public class WishTreeActivity extends AppCompatActivity {
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));
binding.bannerTimer.setText(String.format(Locale.getDefault(), "%02d:%02d:%02d", h, m, s));
} catch (Exception ignored) {}
}
@ -574,7 +589,6 @@ public class WishTreeActivity extends AppCompatActivity {
binding.bottomNavInclude.bottomNavigation.setSelectedItemId(R.id.nav_wish_tree);
UnreadMessageManager.updateBadge(binding.bottomNavInclude.bottomNavigation);
}
// 每次返回页面时刷新数据
loadMyWishes();
}
}

View File

@ -204,7 +204,7 @@ public class WorksAdapter extends RecyclerView.Adapter<WorksAdapter.WorksViewHol
public void onResponse(retrofit2.Call<com.example.livestreaming.net.ApiResponse<Boolean>> call,
retrofit2.Response<com.example.livestreaming.net.ApiResponse<Boolean>> response) {
// 重新启用按钮
likeIcon.setEnabled(true);
like Icon.setEnabled(true);
if (response.isSuccessful() && response.body() != null && response.body().isOk()) {
// 更新数据

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 绳子 -->
<item
android:gravity="top|center_horizontal"
android:top="0dp"
android:left="12dp"
android:right="12dp">
<shape android:shape="rectangle">
<solid android:color="#A0522D"/>
<size android:width="2dp" android:height="12dp"/>
</shape>
</item>
<!-- 许愿牌主体 -->
<item android:top="10dp">
<shape android:shape="rectangle">
<solid android:color="#87CEEB"/>
<corners android:radius="3dp"/>
<stroke android:width="0.5dp" android:color="#4169E1"/>
</shape>
</item>
</layer-list>

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 绳子 -->
<item
android:gravity="top|center_horizontal"
android:top="0dp"
android:left="12dp"
android:right="12dp">
<shape android:shape="rectangle">
<solid android:color="#A0522D"/>
<size android:width="2dp" android:height="12dp"/>
</shape>
</item>
<!-- 许愿牌主体 - 金色 -->
<item android:top="10dp">
<shape android:shape="rectangle">
<solid android:color="#F5DEB3"/>
<corners android:radius="3dp"/>
<stroke android:width="0.5dp" android:color="#DAA520"/>
</shape>
</item>
</layer-list>

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 绳子 -->
<item
android:gravity="top|center_horizontal"
android:top="0dp"
android:left="12dp"
android:right="12dp">
<shape android:shape="rectangle">
<solid android:color="#A0522D"/>
<size android:width="2dp" android:height="12dp"/>
</shape>
</item>
<!-- 许愿牌主体 -->
<item android:top="10dp">
<shape android:shape="rectangle">
<solid android:color="#98D982"/>
<corners android:radius="3dp"/>
<stroke android:width="0.5dp" android:color="#6BBF59"/>
</shape>
</item>
</layer-list>

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 绳子 -->
<item
android:gravity="top|center_horizontal"
android:top="0dp"
android:left="12dp"
android:right="12dp">
<shape android:shape="rectangle">
<solid android:color="#A0522D"/>
<size android:width="2dp" android:height="12dp"/>
</shape>
</item>
<!-- 许愿牌主体 -->
<item android:top="10dp">
<shape android:shape="rectangle">
<solid android:color="#FFB347"/>
<corners android:radius="3dp"/>
<stroke android:width="0.5dp" android:color="#FF8C00"/>
</shape>
</item>
</layer-list>

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 绳子 -->
<item
android:gravity="top|center_horizontal"
android:top="0dp"
android:left="12dp"
android:right="12dp">
<shape android:shape="rectangle">
<solid android:color="#A0522D"/>
<size android:width="2dp" android:height="12dp"/>
</shape>
</item>
<!-- 许愿牌主体 -->
<item android:top="10dp">
<shape android:shape="rectangle">
<solid android:color="#FFB6C1"/>
<corners android:radius="3dp"/>
<stroke android:width="0.5dp" android:color="#FF69B4"/>
</shape>
</item>
</layer-list>

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 绳子 -->
<item
android:gravity="top|center_horizontal"
android:top="0dp"
android:left="12dp"
android:right="12dp">
<shape android:shape="rectangle">
<solid android:color="#A0522D"/>
<size android:width="2dp" android:height="12dp"/>
</shape>
</item>
<!-- 许愿牌主体 -->
<item android:top="10dp">
<shape android:shape="rectangle">
<solid android:color="#DDA0DD"/>
<corners android:radius="3dp"/>
<stroke android:width="0.5dp" android:color="#9370DB"/>
</shape>
</item>
</layer-list>

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 绳子 -->
<item
android:gravity="top|center_horizontal"
android:top="0dp"
android:left="12dp"
android:right="12dp">
<shape android:shape="rectangle">
<solid android:color="#A0522D"/>
<size android:width="2dp" android:height="12dp"/>
</shape>
</item>
<!-- 许愿牌主体 -->
<item android:top="10dp">
<shape android:shape="rectangle">
<solid android:color="#F0E68C"/>
<corners android:radius="3dp"/>
<stroke android:width="0.5dp" android:color="#DAA520"/>
</shape>
</item>
</layer-list>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 258 KiB

After

Width:  |  Height:  |  Size: 4.3 MiB

View File

@ -1,442 +1,362 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/bg_deep_night_gradient">
android:layout_height="match_parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/content"
<FrameLayout
android:id="@+id/rootContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="60dp">
android:paddingBottom="56dp">
<!-- 许愿树背景图 -->
<ImageView
android:id="@+id/wishTreeImage"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:contentDescription="Wish Tree"
android:scaleType="centerCrop"
android:src="@drawable/wish_tree" />
<!-- 心愿牌容器 -->
<FrameLayout
android:id="@+id/wishTagsContainer"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- 心愿牌1 - 左边树枝 -->
<TextView
android:id="@+id/wishTag1"
android:layout_width="26dp"
android:layout_height="68dp"
android:layout_marginStart="18dp"
android:layout_marginTop="200dp"
android:background="@drawable/bg_wish_tag_pink"
android:gravity="center_horizontal"
android:paddingTop="14dp"
android:paddingHorizontal="2dp"
android:text=""
android:textColor="#5D4037"
android:textSize="7sp"
android:lineSpacingExtra="-2dp"
android:visibility="gone"
android:elevation="2dp" />
<!-- 心愿牌2 - 左上树枝 -->
<TextView
android:id="@+id/wishTag2"
android:layout_width="26dp"
android:layout_height="68dp"
android:layout_marginStart="55dp"
android:layout_marginTop="175dp"
android:background="@drawable/bg_wish_tag_green"
android:gravity="center_horizontal"
android:paddingTop="14dp"
android:paddingHorizontal="2dp"
android:text=""
android:textColor="#5D4037"
android:textSize="7sp"
android:lineSpacingExtra="-2dp"
android:visibility="gone"
android:elevation="2dp" />
<!-- 心愿牌3 - 中左树枝 -->
<TextView
android:id="@+id/wishTag3"
android:layout_width="26dp"
android:layout_height="68dp"
android:layout_marginStart="95dp"
android:layout_marginTop="160dp"
android:background="@drawable/bg_wish_tag_gold"
android:gravity="center_horizontal"
android:paddingTop="14dp"
android:paddingHorizontal="2dp"
android:text=""
android:textColor="#5D4037"
android:textSize="7sp"
android:lineSpacingExtra="-2dp"
android:visibility="gone"
android:elevation="2dp" />
<!-- 心愿牌4 - 中间树枝 -->
<TextView
android:id="@+id/wishTag4"
android:layout_width="26dp"
android:layout_height="68dp"
android:layout_marginStart="145dp"
android:layout_marginTop="145dp"
android:background="@drawable/bg_wish_tag_blue"
android:gravity="center_horizontal"
android:paddingTop="14dp"
android:paddingHorizontal="2dp"
android:text=""
android:textColor="#5D4037"
android:textSize="7sp"
android:lineSpacingExtra="-2dp"
android:visibility="gone"
android:elevation="2dp" />
<!-- 心愿牌5 - 中右树枝 -->
<TextView
android:id="@+id/wishTag5"
android:layout_width="26dp"
android:layout_height="68dp"
android:layout_marginStart="200dp"
android:layout_marginTop="155dp"
android:background="@drawable/bg_wish_tag_purple"
android:gravity="center_horizontal"
android:paddingTop="14dp"
android:paddingHorizontal="2dp"
android:text=""
android:textColor="#5D4037"
android:textSize="7sp"
android:lineSpacingExtra="-2dp"
android:visibility="gone"
android:elevation="2dp" />
<!-- 心愿牌6 - 右上树枝 -->
<TextView
android:id="@+id/wishTag6"
android:layout_width="26dp"
android:layout_height="68dp"
android:layout_marginStart="255dp"
android:layout_marginTop="165dp"
android:background="@drawable/bg_wish_tag_yellow"
android:gravity="center_horizontal"
android:paddingTop="14dp"
android:paddingHorizontal="2dp"
android:text=""
android:textColor="#5D4037"
android:textSize="7sp"
android:lineSpacingExtra="-2dp"
android:visibility="gone"
android:elevation="2dp" />
<!-- 心愿牌7 - 右边树枝 -->
<TextView
android:id="@+id/wishTag7"
android:layout_width="26dp"
android:layout_height="68dp"
android:layout_marginStart="310dp"
android:layout_marginTop="185dp"
android:background="@drawable/bg_wish_tag_orange"
android:gravity="center_horizontal"
android:paddingTop="14dp"
android:paddingHorizontal="2dp"
android:text=""
android:textColor="#5D4037"
android:textSize="7sp"
android:lineSpacingExtra="-2dp"
android:visibility="gone"
android:elevation="2dp" />
<!-- 心愿牌8 - 左下树枝 -->
<TextView
android:id="@+id/wishTag8"
android:layout_width="26dp"
android:layout_height="68dp"
android:layout_marginStart="35dp"
android:layout_marginTop="280dp"
android:background="@drawable/bg_wish_tag_green"
android:gravity="center_horizontal"
android:paddingTop="14dp"
android:paddingHorizontal="2dp"
android:text=""
android:textColor="#5D4037"
android:textSize="7sp"
android:lineSpacingExtra="-2dp"
android:visibility="gone"
android:elevation="2dp" />
<!-- 心愿牌9 - 中下树枝 -->
<TextView
android:id="@+id/wishTag9"
android:layout_width="26dp"
android:layout_height="68dp"
android:layout_marginStart="75dp"
android:layout_marginTop="260dp"
android:background="@drawable/bg_wish_tag_blue"
android:gravity="center_horizontal"
android:paddingTop="14dp"
android:paddingHorizontal="2dp"
android:text=""
android:textColor="#5D4037"
android:textSize="7sp"
android:lineSpacingExtra="-2dp"
android:visibility="gone"
android:elevation="2dp" />
<!-- 心愿牌10 - 右下树枝 -->
<TextView
android:id="@+id/wishTag10"
android:layout_width="26dp"
android:layout_height="68dp"
android:layout_marginStart="280dp"
android:layout_marginTop="265dp"
android:background="@drawable/bg_wish_tag_pink"
android:gravity="center_horizontal"
android:paddingTop="14dp"
android:paddingHorizontal="2dp"
android:text=""
android:textColor="#5D4037"
android:textSize="7sp"
android:lineSpacingExtra="-2dp"
android:visibility="gone"
android:elevation="2dp" />
</FrameLayout>
<!-- 顶部栏 -->
<androidx.constraintlayout.widget.ConstraintLayout
<LinearLayout
android:id="@+id/topBar"
android:layout_width="0dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="@dimen/page_margin"
android:paddingTop="@dimen/card_padding"
android:paddingBottom="@dimen/spacing_sm"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
android:orientation="horizontal"
android:gravity="center_vertical"
android:paddingHorizontal="16dp"
android:paddingTop="8dp"
android:paddingBottom="4dp">
<ImageView
android:id="@+id/title"
android:layout_width="0dp"
android:layout_height="28dp"
android:layout_height="24dp"
android:layout_weight="1"
android:adjustViewBounds="true"
android:contentDescription="WishTree"
android:scaleType="fitStart"
android:src="@drawable/wish_tree_title"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/searchButton"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
android:src="@drawable/wish_tree_title" />
<ImageButton
android:id="@+id/searchButton"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_width="36dp"
android:layout_height="36dp"
android:background="@drawable/bg_glass_button"
android:contentDescription="Search"
android:padding="@dimen/spacing_sm"
android:padding="6dp"
android:src="@drawable/ic_search_24"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/notifyButton"
app:layout_constraintTop_toTopOf="parent"
app:tint="@color/white" />
<ImageButton
android:id="@+id/notifyButton"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginStart="@dimen/spacing_sm"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_marginStart="8dp"
android:background="@drawable/bg_glass_button"
android:contentDescription="Notifications"
android:padding="@dimen/spacing_sm"
android:padding="6dp"
android:src="@drawable/ic_notifications_24"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:tint="@color/white" />
</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>
<!-- 活动横幅 - 玻璃拟态 -->
<androidx.constraintlayout.widget.ConstraintLayout
<!-- 活动横幅 -->
<LinearLayout
android:id="@+id/banner"
android:layout_width="0dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="@dimen/page_margin"
android:layout_marginHorizontal="12dp"
android:layout_marginTop="48dp"
android:background="@drawable/bg_banner_glass"
android:paddingHorizontal="@dimen/card_padding"
android:paddingVertical="@dimen/spacing_sm"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/topBar">
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingHorizontal="10dp"
android:paddingVertical="6dp">
<TextView
android:id="@+id/bannerText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ellipsize="end"
android:maxLines="1"
android:text="✨ 元旦许愿树 | 任意充值即翻倍"
android:text="✨ 许愿树 | 许下心愿,愿望成真"
android:textColor="@color/white"
android:textSize="@dimen/text_md"
android:textStyle="bold"
android:shadowColor="#80000000"
android:shadowDx="1"
android:shadowDy="1"
android:shadowRadius="2"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/bannerTimer"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
android:textSize="12sp"
android:textStyle="bold" />
<TextView
android:id="@+id/bannerTimer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/bg_timer_pill"
android:paddingHorizontal="@dimen/spacing_md"
android:paddingVertical="@dimen/spacing_xs"
android:paddingHorizontal="8dp"
android:paddingVertical="3dp"
android:text="12:30:05"
android:textColor="@color/white"
android:textSize="@dimen/text_sm"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
android:textSize="11sp"
android:textStyle="bold" />
</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>
<!-- 树形光晕效果 -->
<View
android:id="@+id/treeGlow"
android:layout_width="400dp"
android:layout_height="400dp"
android:background="@drawable/bg_tree_glow_radial"
app:layout_constraintBottom_toTopOf="@id/bottomArea"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/banner"
app:layout_constraintVertical_bias="0.4" />
<!-- 许愿树背景图 -->
<ImageView
android:id="@+id/wishTreeImage"
android:layout_width="0dp"
android:layout_height="0dp"
android:clickable="false"
android:focusable="false"
android:contentDescription="Wish Tree"
android:scaleType="centerCrop"
android:src="@drawable/wish_tree"
app:layout_constraintBottom_toTopOf="@id/bottomArea"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/banner" />
<!-- 心愿卡片1 - 左上 -->
<TextView
android:id="@+id/wishCard1"
android:layout_width="54dp"
android:layout_height="70dp"
android:background="@drawable/bg_wish_card_glass"
android:clickable="true"
android:focusable="true"
android:elevation="6dp"
android:gravity="center"
android:padding="@dimen/spacing_xs"
android:text=""
android:textColor="@color/white"
android:textSize="@dimen/text_xs"
android:shadowColor="#80000000"
android:shadowDx="1"
android:shadowDy="1"
android:shadowRadius="2"
app:layout_constraintHorizontal_bias="0.12"
app:layout_constraintVertical_bias="0.15"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/banner"
app:layout_constraintBottom_toTopOf="@id/bottomArea" />
<!-- 心愿卡片2 - 左中上 -->
<TextView
android:id="@+id/wishCard2"
android:layout_width="60dp"
android:layout_height="78dp"
android:background="@drawable/bg_wish_card_glass"
android:clickable="true"
android:focusable="true"
android:elevation="6dp"
android:gravity="center"
android:padding="@dimen/spacing_xs"
android:text=""
android:textColor="@color/white"
android:textSize="@dimen/text_sm"
android:shadowColor="#80000000"
android:shadowDx="1"
android:shadowDy="1"
android:shadowRadius="2"
app:layout_constraintHorizontal_bias="0.32"
app:layout_constraintVertical_bias="0.08"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/banner"
app:layout_constraintBottom_toTopOf="@id/bottomArea" />
<!-- 心愿卡片3 - 右上 -->
<TextView
android:id="@+id/wishCard3"
android:layout_width="54dp"
android:layout_height="70dp"
android:background="@drawable/bg_wish_card_glass"
android:clickable="true"
android:focusable="true"
android:elevation="6dp"
android:gravity="center"
android:padding="@dimen/spacing_xs"
android:text=""
android:textColor="@color/white"
android:textSize="@dimen/text_xs"
android:shadowColor="#80000000"
android:shadowDx="1"
android:shadowDy="1"
android:shadowRadius="2"
app:layout_constraintHorizontal_bias="0.88"
app:layout_constraintVertical_bias="0.12"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/banner"
app:layout_constraintBottom_toTopOf="@id/bottomArea" />
<!-- 心愿卡片4 - 左中 -->
<TextView
android:id="@+id/wishCard4"
android:layout_width="60dp"
android:layout_height="78dp"
android:background="@drawable/bg_wish_card_glass"
android:clickable="true"
android:focusable="true"
android:elevation="6dp"
android:gravity="center"
android:padding="@dimen/spacing_xs"
android:text=""
android:textColor="@color/white"
android:textSize="@dimen/text_sm"
android:shadowColor="#80000000"
android:shadowDx="1"
android:shadowDy="1"
android:shadowRadius="2"
app:layout_constraintHorizontal_bias="0.05"
app:layout_constraintVertical_bias="0.38"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/banner"
app:layout_constraintBottom_toTopOf="@id/bottomArea" />
<!-- 添加心愿按钮 - 中央偏右 -->
<TextView
android:id="@+id/addWishCard"
android:layout_width="66dp"
android:layout_height="85dp"
android:background="@drawable/bg_wish_card_add_glass"
android:clickable="true"
android:focusable="true"
android:elevation="8dp"
android:gravity="center"
android:padding="@dimen/spacing_xs"
android:text="心愿\n✦"
android:textColor="@color/shimmer_gold"
android:textSize="@dimen/text_md"
android:textStyle="bold"
android:shadowColor="#80000000"
android:shadowDx="1"
android:shadowDy="1"
android:shadowRadius="3"
app:layout_constraintHorizontal_bias="0.72"
app:layout_constraintVertical_bias="0.32"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/banner"
app:layout_constraintBottom_toTopOf="@id/bottomArea" />
<!-- 心愿卡片5 - 右中 -->
<TextView
android:id="@+id/wishCard5"
android:layout_width="54dp"
android:layout_height="70dp"
android:background="@drawable/bg_wish_card_glass"
android:clickable="true"
android:focusable="true"
android:elevation="6dp"
android:gravity="center"
android:padding="@dimen/spacing_xs"
android:text=""
android:textColor="@color/white"
android:textSize="@dimen/text_xs"
android:shadowColor="#80000000"
android:shadowDx="1"
android:shadowDy="1"
android:shadowRadius="2"
app:layout_constraintHorizontal_bias="0.92"
app:layout_constraintVertical_bias="0.42"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/banner"
app:layout_constraintBottom_toTopOf="@id/bottomArea" />
<!-- 心愿卡片6 - 左下 -->
<TextView
android:id="@+id/wishCard6"
android:layout_width="60dp"
android:layout_height="78dp"
android:background="@drawable/bg_wish_card_glass"
android:clickable="true"
android:focusable="true"
android:elevation="6dp"
android:gravity="center"
android:padding="@dimen/spacing_xs"
android:text=""
android:textColor="@color/white"
android:textSize="@dimen/text_sm"
android:shadowColor="#80000000"
android:shadowDx="1"
android:shadowDy="1"
android:shadowRadius="2"
app:layout_constraintHorizontal_bias="0.18"
app:layout_constraintVertical_bias="0.58"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/banner"
app:layout_constraintBottom_toTopOf="@id/bottomArea" />
<!-- 心愿卡片7 - 右下 -->
<TextView
android:id="@+id/wishCard7"
android:layout_width="54dp"
android:layout_height="70dp"
android:background="@drawable/bg_wish_card_glass"
android:clickable="true"
android:focusable="true"
android:elevation="6dp"
android:gravity="center"
android:padding="@dimen/spacing_xs"
android:text=""
android:textColor="@color/white"
android:textSize="@dimen/text_xs"
android:shadowColor="#80000000"
android:shadowDx="1"
android:shadowDy="1"
android:shadowRadius="2"
app:layout_constraintHorizontal_bias="0.82"
app:layout_constraintVertical_bias="0.62"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/banner"
app:layout_constraintBottom_toTopOf="@id/bottomArea" />
<!-- 树干上的金色竖向文字 -->
<TextView
android:id="@+id/tvTrunkText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="100dp"
android:background="@drawable/bg_glass_card"
android:gravity="center"
android:lineSpacingExtra="8dp"
android:paddingHorizontal="@dimen/spacing_md"
android:paddingVertical="@dimen/page_margin"
android:text="元\n旦\n许\n愿\n树"
android:textColor="@color/shimmer_gold"
android:textSize="@dimen/text_xl"
android:textStyle="bold"
android:shadowColor="#80000000"
android:shadowDx="2"
android:shadowDy="2"
android:shadowRadius="4"
app:layout_constraintBottom_toTopOf="@id/bottomArea"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<!-- 底部区域 - 玻璃拟态 -->
<androidx.constraintlayout.widget.ConstraintLayout
<!-- 底部区域 -->
<LinearLayout
android:id="@+id/bottomArea"
android:layout_width="0dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="@drawable/bg_bottom_area_glass"
android:paddingHorizontal="@dimen/page_margin"
android:paddingTop="@dimen/page_margin"
android:paddingBottom="@dimen/spacing_md"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
android:orientation="vertical"
android:paddingHorizontal="16dp"
android:paddingTop="12dp"
android:paddingBottom="8dp">
<!-- 进度信息 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<!-- 进度标签 -->
<TextView
android:id="@+id/tvWishLabel"
android:layout_width="wrap_content"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="✨ 祈愿进度"
android:textColor="@color/glass_white_60"
android:textSize="@dimen/text_sm"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
android:textSize="11sp" />
<!-- 进度数值 -->
<TextView
android:id="@+id/tvWishCount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="0/100"
android:text="祈愿值0/100"
android:textColor="@color/shimmer_gold"
android:textSize="@dimen/text_md"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
android:textSize="12sp"
android:textStyle="bold" />
</LinearLayout>
<!-- 进度条 -->
<ProgressBar
android:id="@+id/progressWish"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="0dp"
android:layout_height="8dp"
android:layout_marginTop="@dimen/spacing_sm"
android:layout_width="match_parent"
android:layout_height="6dp"
android:layout_marginTop="6dp"
android:max="100"
android:progress="35"
android:progressDrawable="@drawable/progress_wish_gradient"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvWishLabel" />
android:progress="0"
android:progressDrawable="@drawable/progress_wish_gradient" />
<!-- 祈愿按钮 -->
<com.google.android.material.button.MaterialButton
android:id="@+id/btnMakeWish"
android:layout_width="0dp"
android:layout_height="@dimen/button_height"
android:layout_marginTop="@dimen/spacing_lg"
android:layout_width="match_parent"
android:layout_height="44dp"
android:layout_marginTop="10dp"
android:background="@drawable/bg_shimmer_gold_button"
android:stateListAnimator="@null"
android:text="🌟 前往祈愿"
android:text="🌟 许下心愿"
android:textColor="@color/deep_night_bg"
android:textSize="@dimen/text_lg"
android:textSize="15sp"
android:textStyle="bold"
app:backgroundTint="@null"
app:cornerRadius="@dimen/radius_large"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/progressWish" />
app:cornerRadius="22dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</FrameLayout>
<include
android:id="@+id/bottomNavInclude"