zhibo/android-app/app/src/main/java/com/example/livestreaming/ProfileActivity.java
2026-01-06 14:24:42 +08:00

1086 lines
47 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

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

package com.example.livestreaming;
import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.FileProvider;
import androidx.appcompat.app.AlertDialog;
import androidx.recyclerview.widget.GridLayoutManager;
import com.bumptech.glide.Glide;
import com.example.livestreaming.BuildConfig;
import com.example.livestreaming.databinding.ActivityProfileBinding;
import com.example.livestreaming.ShareUtils;
import com.example.livestreaming.net.ApiClient;
import com.example.livestreaming.net.ApiResponse;
import com.example.livestreaming.net.UserInfoResponse;
import com.google.android.material.bottomnavigation.BottomNavigationView;
import com.google.android.material.bottomsheet.BottomSheetDialog;
import java.util.List;
import java.io.File;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
public class ProfileActivity extends AppCompatActivity {
private static final String TAG = "ProfileActivity";
private ActivityProfileBinding binding;
private static final String PREFS_NAME = "profile_prefs";
private static final String KEY_NAME = "profile_name";
private static final String KEY_BIO = "profile_bio";
private static final String KEY_LEVEL = "profile_level";
private static final String KEY_FANS_BADGE = "profile_fans_badge";
private static final String KEY_BADGE = "profile_badge";
private static final String KEY_AVATAR_RES = "profile_avatar_res";
private static final String KEY_AVATAR_URI = "profile_avatar_uri";
private static final String KEY_BIRTHDAY = "profile_birthday";
private static final String KEY_GENDER = "profile_gender";
private static final String KEY_LOCATION = "profile_location";
private static final String BIO_HINT_TEXT = "填写个人签名更容易获得关注,点击此处添加";
private ActivityResultLauncher<Intent> editProfileLauncher;
private UserWorksAdapter worksAdapter;
public static void start(Context context) {
Intent intent = new Intent(context, ProfileActivity.class);
context.startActivity(intent);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityProfileBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
// 注册编辑资料页面的结果监听
editProfileLauncher = registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
result -> {
// 当从EditProfileActivity返回时立即刷新所有数据
loadProfileFromPrefs();
loadAndDisplayTags();
loadProfileInfo();
}
);
loadProfileFromPrefs();
loadUserInfoFromServer(); // 从服务器加载用户信息
loadAndDisplayTags();
loadProfileInfo();
loadFollowStats(); // 加载关注统计
setupEditableAreas();
setupAvatarClick();
setupNavigationClicks();
setupWorksRecycler();
setupProfileTabs();
BottomNavigationView bottomNavigation = binding.bottomNavInclude.bottomNavigation;
bottomNavigation.setSelectedItemId(R.id.nav_profile);
// 更新未读消息徽章
UnreadMessageManager.updateBadge(bottomNavigation);
bottomNavigation.setOnItemSelectedListener(item -> {
int id = item.getItemId();
if (id == R.id.nav_home) {
startActivity(new Intent(this, MainActivity.class));
finish();
return true;
}
if (id == R.id.nav_friends) {
startActivity(new Intent(this, FishPondWebViewActivity.class));
finish();
return true;
}
if (id == R.id.nav_wish_tree) {
WishTreeWebViewActivity.start(this);
finish();
return true;
}
if (id == R.id.nav_messages) {
MessagesActivity.start(this);
finish();
return true;
}
if (id == R.id.nav_profile) {
return true;
}
return true;
});
}
private void loadProfileFromPrefs() {
// TODO: 接入后端接口 - 获取用户资料
// 接口路径: GET /api/users/{userId}/profile
// 请求参数:
// - userId: 用户ID路径参数当前用户从token中获取
// 返回数据格式: ApiResponse<UserProfile>
// UserProfile对象应包含: id, name, avatarUrl, bio, level, badge, birthday, gender, location,
// followingCount, fansCount, likesCount等字段
// 首次加载时从接口获取,后续可从本地缓存读取
String n = getSharedPreferences(PREFS_NAME, MODE_PRIVATE).getString(KEY_NAME, null);
if (!TextUtils.isEmpty(n)) binding.name.setText(n);
String bio = getSharedPreferences(PREFS_NAME, MODE_PRIVATE).getString(KEY_BIO, null);
if (!TextUtils.isEmpty(bio) && !BIO_HINT_TEXT.equals(bio)) {
binding.bioText.setText(bio);
binding.bioText.setTextColor(0xFF111111);
} else {
binding.bioText.setText(BIO_HINT_TEXT);
binding.bioText.setTextColor(0xFF999999);
}
String avatarUri = getSharedPreferences(PREFS_NAME, MODE_PRIVATE).getString(KEY_AVATAR_URI, null);
if (!TextUtils.isEmpty(avatarUri)) {
Uri uri = Uri.parse(avatarUri);
// 如果是 file:// 协议,尝试转换为 FileProvider URI
if ("file".equals(uri.getScheme())) {
try {
java.io.File file = new java.io.File(uri.getPath());
if (file.exists()) {
uri = FileProvider.getUriForFile(
this,
getPackageName() + ".fileprovider",
file
);
}
} catch (Exception e) {
// 如果转换失败,使用原始 URI
}
}
Glide.with(this)
.load(uri)
.circleCrop()
.error(R.drawable.ic_account_circle_24)
.placeholder(R.drawable.ic_account_circle_24)
.into(binding.avatar);
} else {
int avatarRes = getSharedPreferences(PREFS_NAME, MODE_PRIVATE).getInt(KEY_AVATAR_RES, 0);
if (avatarRes != 0) {
Glide.with(this)
.load(avatarRes)
.circleCrop()
.error(R.drawable.ic_account_circle_24)
.into(binding.avatar);
} else {
binding.avatar.setImageResource(R.drawable.ic_account_circle_24);
}
}
// 等级/称号/徽章:保持固定显示(例如“月亮/星耀/至尊”),不从本地缓存覆盖。
}
/**
* 从服务器加载用户信息并同步到本地
*/
private void loadUserInfoFromServer() {
if (!AuthHelper.isLoggedIn(this)) {
return;
}
ApiClient.getService(this).getUserInfo().enqueue(new Callback<ApiResponse<UserInfoResponse>>() {
@Override
public void onResponse(Call<ApiResponse<UserInfoResponse>> call, Response<ApiResponse<UserInfoResponse>> response) {
if (response.isSuccessful() && response.body() != null && response.body().isOk()) {
UserInfoResponse userInfo = response.body().getData();
if (userInfo != null) {
syncUserInfoToLocal(userInfo);
}
}
}
@Override
public void onFailure(Call<ApiResponse<UserInfoResponse>> call, Throwable t) {
Log.e(TAG, "加载用户信息失败: " + t.getMessage());
}
});
}
/**
* 同步服务器用户信息到本地并更新UI
*/
private void syncUserInfoToLocal(UserInfoResponse userInfo) {
android.content.SharedPreferences.Editor editor = getSharedPreferences(PREFS_NAME, MODE_PRIVATE).edit();
// 同步昵称
if (!TextUtils.isEmpty(userInfo.getNickname())) {
editor.putString(KEY_NAME, userInfo.getNickname());
binding.name.setText(userInfo.getNickname());
}
// 同步个性签名
if (!TextUtils.isEmpty(userInfo.getMark())) {
editor.putString(KEY_BIO, userInfo.getMark());
binding.bioText.setText(userInfo.getMark());
binding.bioText.setTextColor(0xFF111111);
}
// 同步头像
if (!TextUtils.isEmpty(userInfo.getAvatar())) {
String avatarUrl = userInfo.getAvatar();
String baseUrl = ApiClient.getCurrentBaseUrl(ProfileActivity.this);
// 处理相对路径
if (!avatarUrl.startsWith("http://") && !avatarUrl.startsWith("https://")) {
if (avatarUrl.startsWith("crmebimage/")) {
avatarUrl = baseUrl.replace("/api/", "/") + avatarUrl;
}
}
editor.putString(KEY_AVATAR_URI, avatarUrl);
Glide.with(ProfileActivity.this)
.load(avatarUrl)
.circleCrop()
.error(R.drawable.ic_account_circle_24)
.placeholder(R.drawable.ic_account_circle_24)
.into(binding.avatar);
}
// 同步生日
if (!TextUtils.isEmpty(userInfo.getBirthday())) {
editor.putString(KEY_BIRTHDAY, userInfo.getBirthday());
}
// 同步性别
if (userInfo.getSex() != null) {
String gender = "";
switch (userInfo.getSex()) {
case 1: gender = ""; break;
case 2: gender = ""; break;
case 3: gender = "保密"; break;
}
if (!TextUtils.isEmpty(gender)) {
editor.putString(KEY_GENDER, gender);
}
}
// 同步地址
if (!TextUtils.isEmpty(userInfo.getAddres())) {
editor.putString(KEY_LOCATION, userInfo.getAddres());
}
editor.apply();
// 刷新标签显示
loadAndDisplayTags();
loadProfileInfo();
}
private void setupEditableAreas() {
// TODO: 接入后端接口 - 更新用户资料
// 接口路径: PUT /api/users/{userId}/profile
// 请求参数:
// - userId: 用户ID路径参数从token中获取
// - name (可选): 昵称
// - bio (可选): 个人签名
// - avatarUrl (可选): 头像URL
// - birthday (可选): 生日
// - gender (可选): 性别
// - location (可选): 所在地
// 返回数据格式: ApiResponse<UserProfile>
// 更新成功后,同步更新本地缓存和界面显示
binding.name.setOnClickListener(v -> showEditDialog("编辑昵称", binding.name.getText() != null ? binding.name.getText().toString() : "", text -> {
binding.name.setText(text);
getSharedPreferences(PREFS_NAME, MODE_PRIVATE).edit().putString(KEY_NAME, text).apply();
}));
binding.bioText.setOnClickListener(v -> {
String current = binding.bioText.getText() != null ? binding.bioText.getText().toString() : "";
String initial = BIO_HINT_TEXT.equals(current) ? "" : current;
showEditDialog("编辑签名", initial, text -> {
if (TextUtils.isEmpty(text) || BIO_HINT_TEXT.equals(text)) {
binding.bioText.setText(BIO_HINT_TEXT);
binding.bioText.setTextColor(0xFF999999);
getSharedPreferences(PREFS_NAME, MODE_PRIVATE).edit().remove(KEY_BIO).apply();
} else {
binding.bioText.setText(text);
binding.bioText.setTextColor(0xFF111111);
getSharedPreferences(PREFS_NAME, MODE_PRIVATE).edit().putString(KEY_BIO, text).apply();
}
});
});
}
private void setupAvatarClick() {
binding.avatar.setOnClickListener(v -> {
AvatarViewerDialog dialog = AvatarViewerDialog.create(this);
// 优先从SharedPreferences读取最新的头像信息因为ImageView可能还在加载中
String avatarUri = getSharedPreferences(PREFS_NAME, MODE_PRIVATE).getString(KEY_AVATAR_URI, null);
int avatarRes = getSharedPreferences(PREFS_NAME, MODE_PRIVATE).getInt(KEY_AVATAR_RES, 0);
if (!TextUtils.isEmpty(avatarUri)) {
// 使用URI加载确保能正确显示
dialog.setAvatarUri(Uri.parse(avatarUri));
} else if (avatarRes != 0) {
dialog.setAvatarResId(avatarRes);
} else {
// 如果都没有尝试从ImageView获取Drawable
Drawable drawable = binding.avatar.getDrawable();
if (drawable != null) {
dialog.setAvatarDrawable(drawable);
} else {
dialog.setAvatarResId(R.drawable.ic_account_circle_24);
}
}
dialog.show();
});
}
private void setupNavigationClicks() {
binding.topActionSearch.setOnClickListener(v -> TabPlaceholderActivity.start(this, "定位/发现"));
binding.topActionClock.setOnClickListener(v -> {
// 检查登录状态,观看历史需要登录
if (!AuthHelper.requireLogin(this, "查看观看历史需要登录")) {
return;
}
MyRecordsActivity.start(this);
});
binding.topActionMore.setOnClickListener(v -> showMoreOptionsMenu());
binding.copyIdBtn.setOnClickListener(v -> {
String idText = binding.idLine.getText() != null ? binding.idLine.getText().toString() : "";
if (TextUtils.isEmpty(idText)) return;
String digits = idText.replaceAll("\\D+", "");
if (TextUtils.isEmpty(digits)) return;
ClipboardManager cm = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
if (cm != null) {
cm.setPrimaryClip(ClipData.newPlainText("id", digits));
Toast.makeText(this, "已复制:" + digits, Toast.LENGTH_SHORT).show();
}
});
// TODO: 接入后端接口 - 获取关注/粉丝/获赞数量
// 接口路径: GET /api/users/{userId}/stats
// 请求参数:
// - userId: 用户ID路径参数
// 返回数据格式: ApiResponse<{followingCount: number, fansCount: number, likesCount: number}>
// 在ProfileActivity加载时调用更新关注、粉丝、获赞数量显示
binding.following.setOnClickListener(v -> {
// 检查登录状态,查看关注列表需要登录
if (!AuthHelper.requireLogin(this, "查看关注列表需要登录")) {
return;
}
FollowingListActivity.start(this);
});
binding.followers.setOnClickListener(v -> {
// 检查登录状态,查看粉丝列表需要登录
if (!AuthHelper.requireLogin(this, "查看粉丝列表需要登录")) {
return;
}
FansListActivity.start(this);
});
binding.likes.setOnClickListener(v -> {
// 检查登录状态,查看获赞列表需要登录
if (!AuthHelper.requireLogin(this, "查看获赞列表需要登录")) {
return;
}
LikesListActivity.start(this);
});
binding.action1.setOnClickListener(v -> {
// 我的关注
if (!AuthHelper.requireLogin(this, "查看关注列表需要登录")) {
return;
}
startActivity(new Intent(this, FollowingActivity.class));
});
binding.action2.setOnClickListener(v -> {
// 我的收藏(点赞的直播间)
if (!AuthHelper.requireLogin(this, "查看收藏需要登录")) {
return;
}
startActivity(new Intent(this, LikedRoomsActivity.class));
});
binding.action3.setOnClickListener(v -> startActivity(new Intent(this, MyFriendsActivity.class)));
binding.action4.setOnClickListener(v -> {
// 我的记录 - 跳转到统一记录页面
if (!AuthHelper.requireLogin(this, "查看记录需要登录")) {
return;
}
MyRecordsActivity.start(this);
});
binding.editProfile.setOnClickListener(v -> {
// 检查登录状态,编辑资料需要登录
if (!AuthHelper.requireLogin(this, "编辑资料需要登录")) {
return;
}
Intent intent = new Intent(this, EditProfileActivity.class);
editProfileLauncher.launch(intent);
});
binding.shareHome.setOnClickListener(v -> {
// 检查登录状态,分享个人主页需要登录
if (!AuthHelper.requireLogin(this, "分享个人主页需要登录")) {
return;
}
showShareProfileDialog();
});
// 主播中心按钮点击事件
binding.streamerCenterBtn.setOnClickListener(v -> {
StreamerCenterActivity.start(this);
});
binding.addFriendBtn.setOnClickListener(v -> {
// 检查登录状态,添加好友需要登录
if (!AuthHelper.requireLogin(this, "添加好友需要登录")) {
return;
}
AddFriendActivity.start(this);
});
// 我的钱包按钮点击事件
binding.walletButton.setOnClickListener(v -> {
// 检查登录状态,查看钱包需要登录
if (!AuthHelper.requireLogin(this, "查看钱包需要登录")) {
return;
}
startActivity(new Intent(this, WalletActivity.class));
});
}
private void setupProfileTabs() {
showTab(0);
binding.profileTabs.addOnTabSelectedListener(new com.google.android.material.tabs.TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(com.google.android.material.tabs.TabLayout.Tab tab) {
if (tab == null) return;
showTab(tab.getPosition());
}
@Override
public void onTabUnselected(com.google.android.material.tabs.TabLayout.Tab tab) {
}
@Override
public void onTabReselected(com.google.android.material.tabs.TabLayout.Tab tab) {
if (tab == null) return;
showTab(tab.getPosition());
}
});
// TODO: 接入后端接口 - 发布作品
// 接口路径: POST /api/works
// 请求参数:
// - userId: 用户ID从token中获取
// - title: 作品标题
// - description: 作品描述(可选)
// - coverUrl: 封面图片URL必填需要先上传图片
// - videoUrl (可选): 视频URL如果是视频作品
// - images (可选): 图片URL列表如果是图片作品
// 返回数据格式: ApiResponse<WorkItem>
// WorkItem对象应包含: id, title, coverUrl, likeCount, viewCount, publishTime等字段
// 发布成功后,刷新作品列表显示
// 空状态的发布按钮
binding.worksPublishBtn.setOnClickListener(v -> {
// 检查登录状态,发布作品需要登录
if (!AuthHelper.requireLogin(this, "发布作品需要登录")) {
return;
}
PublishWorkActivity.start(this);
});
// 悬浮按钮(固定显示)- 已隐藏
// binding.fabPublishWork.setOnClickListener(v -> {
// // 检查登录状态,发布作品需要登录
// if (!AuthHelper.requireLogin(this, "发布作品需要登录")) {
// return;
// }
// PublishWorkActivity.start(this);
// });
binding.likedGoBrowseBtn.setOnClickListener(v -> startActivity(new Intent(this, MainActivity.class)));
binding.favGoBrowseBtn.setOnClickListener(v -> startActivity(new Intent(this, MainActivity.class)));
binding.profileEditFromTab.setOnClickListener(v -> {
// 检查登录状态,编辑资料需要登录
if (!AuthHelper.requireLogin(this, "编辑资料需要登录")) {
return;
}
Intent intent = new Intent(this, EditProfileActivity.class);
editProfileLauncher.launch(intent);
});
}
private void setupWorksRecycler() {
worksAdapter = new UserWorksAdapter();
worksAdapter.setOnWorkClickListener(workItem -> {
if (workItem != null && !TextUtils.isEmpty(workItem.getId())) {
WorkDetailActivity.start(this, workItem.getId());
}
});
binding.worksRecycler.setLayoutManager(new GridLayoutManager(this, 3));
binding.worksRecycler.setAdapter(worksAdapter);
loadWorks();
}
private void loadWorks() {
// TODO: 接入后端接口 - 获取当前用户的作品列表
// 接口路径: GET /api/users/{userId}/works
// 请求方法: GET
// 请求头: Authorization: Bearer {token} (必填从AuthStore获取)
// 路径参数:
// - userId: String (必填) - 当前用户ID从token中解析获取
// 请求参数Query:
// - page: int (可选默认1) - 页码
// - pageSize: int (可选默认20) - 每页数量
// 返回数据格式: ApiResponse<PageResult<WorkItem>>
// 实现步骤:
// 1. 从AuthStore获取token解析userId或从用户信息中获取
// 2. 调用接口获取作品列表
// 3. 更新UI显示作品列表或空状态
// 4. 处理错误情况(网络错误、未登录等)
// 注意: 此方法在onResume时也会调用需要避免重复请求
// 临时:从本地存储加载(等待后端接口)
List<WorkItem> works = WorkManager.getAllWorks(this);
if (works != null && !works.isEmpty()) {
binding.worksRecycler.setVisibility(View.VISIBLE);
binding.worksEmptyState.setVisibility(View.GONE);
worksAdapter.submitList(works);
} else {
binding.worksRecycler.setVisibility(View.GONE);
binding.worksEmptyState.setVisibility(View.VISIBLE);
}
}
private void showTab(int index) {
// TODO: 接入后端接口 - 获取用户作品列表
// 接口路径: GET /api/users/{userId}/works
// 请求参数:
// - userId: 用户ID从token中获取
// - page (可选): 页码
// - pageSize (可选): 每页数量
// 返回数据格式: ApiResponse<List<WorkItem>>
// WorkItem对象应包含: id, title, coverUrl, likeCount, viewCount, publishTime等字段
// TODO: 接入后端接口 - 获取用户收藏列表
// 接口路径: GET /api/users/{userId}/favorites
// 请求参数:
// - userId: 用户ID从token中获取
// - page (可选): 页码
// - pageSize (可选): 每页数量
// 返回数据格式: ApiResponse<List<WorkItem>>
// TODO: 接入后端接口 - 获取用户赞过的作品列表
// 接口路径: GET /api/users/{userId}/liked
// 请求参数:
// - userId: 用户ID从token中获取
// - page (可选): 页码
// - pageSize (可选): 每页数量
// 返回数据格式: ApiResponse<List<WorkItem>>
// 标签页顺序0-作品, 1-收藏, 2-赞过
binding.tabWorks.setVisibility(index == 0 ? View.VISIBLE : View.GONE);
binding.tabFavorites.setVisibility(index == 1 ? View.VISIBLE : View.GONE);
binding.tabLiked.setVisibility(index == 2 ? View.VISIBLE : View.GONE);
// 当切换到作品标签页时,重新加载作品列表
if (index == 0) {
loadWorks();
}
// "资料"标签页已移除
}
private interface OnTextSaved {
void onSaved(String text);
}
private void showEditDialog(String title, String initialValue, OnTextSaved onSaved) {
EditText editText = new EditText(this);
editText.setText(initialValue != null ? initialValue : "");
editText.setSelection(editText.getText() != null ? editText.getText().length() : 0);
editText.setTextColor(0xFF111111);
editText.setHintTextColor(0xFF999999);
if ("编辑签名".equals(title)) {
editText.setHint(BIO_HINT_TEXT);
}
int pad = (int) (16 * getResources().getDisplayMetrics().density);
editText.setPadding(pad, pad, pad, pad);
new AlertDialog.Builder(this)
.setTitle(title)
.setView(editText)
.setNegativeButton("取消", null)
.setPositiveButton("保存", (d, w) -> {
String t = editText.getText() != null ? editText.getText().toString().trim() : "";
if (onSaved != null) onSaved.onSaved(t);
})
.show();
}
@Override
protected void onResume() {
super.onResume();
if (binding != null) {
loadProfileFromPrefs();
loadAndDisplayTags();
loadProfileInfo();
loadFollowStats(); // 刷新关注统计
loadWalletBalance(); // 刷新钱包余额
loadWorks(); // 重新加载作品列表
BottomNavigationView bottomNav = binding.bottomNavInclude.bottomNavigation;
bottomNav.setSelectedItemId(R.id.nav_profile);
// 更新未读消息徽章
UnreadMessageManager.updateBadge(bottomNav);
// 检查主播状态并显示/隐藏主播中心按钮
checkAndUpdateStreamerButton();
}
}
/**
* 检查主播状态并更新主播中心按钮的显示
*/
private void checkAndUpdateStreamerButton() {
// 如果用户未登录,隐藏主播中心按钮
if (!AuthHelper.isLoggedIn(this)) {
if (binding.streamerCenterBtn != null) {
binding.streamerCenterBtn.setVisibility(View.GONE);
}
return;
}
// 检查主播资格
ApiClient.getService(getApplicationContext()).checkStreamerStatus()
.enqueue(new Callback<ApiResponse<java.util.Map<String, Object>>>() {
@Override
public void onResponse(Call<ApiResponse<java.util.Map<String, Object>>> call,
Response<ApiResponse<java.util.Map<String, Object>>> response) {
if (!response.isSuccessful() || response.body() == null) {
// 接口调用失败,隐藏按钮
if (binding.streamerCenterBtn != null) {
binding.streamerCenterBtn.setVisibility(View.GONE);
}
return;
}
ApiResponse<java.util.Map<String, Object>> body = response.body();
if (body.getCode() != 200 || body.getData() == null) {
// 接口返回错误,隐藏按钮
if (binding.streamerCenterBtn != null) {
binding.streamerCenterBtn.setVisibility(View.GONE);
}
return;
}
java.util.Map<String, Object> data = body.getData();
Boolean isStreamer = data.get("isStreamer") != null && (Boolean) data.get("isStreamer");
Boolean isBanned = data.get("isBanned") != null && (Boolean) data.get("isBanned");
// 只有认证主播且未被封禁才显示主播中心按钮
if (isStreamer && !isBanned && binding.streamerCenterBtn != null) {
binding.streamerCenterBtn.setVisibility(View.VISIBLE);
} else if (binding.streamerCenterBtn != null) {
binding.streamerCenterBtn.setVisibility(View.GONE);
}
}
@Override
public void onFailure(Call<ApiResponse<java.util.Map<String, Object>>> call, Throwable t) {
// 网络错误,隐藏按钮
if (binding.streamerCenterBtn != null) {
binding.streamerCenterBtn.setVisibility(View.GONE);
}
}
});
}
private void loadAndDisplayTags() {
String location = getSharedPreferences(PREFS_NAME, MODE_PRIVATE).getString(KEY_LOCATION, "");
String gender = getSharedPreferences(PREFS_NAME, MODE_PRIVATE).getString(KEY_GENDER, "");
String birthday = getSharedPreferences(PREFS_NAME, MODE_PRIVATE).getString(KEY_BIRTHDAY, "");
// 设置所在地标签 - 支持"省份-城市"格式
if (!TextUtils.isEmpty(location)) {
// 将"省份-城市"格式转换为"省份·城市"显示
String displayLocation = location.replace("-", "·");
binding.tagLocation.setText("IP" + displayLocation);
binding.tagLocation.setVisibility(View.VISIBLE);
} else {
binding.tagLocation.setText("IP广西");
binding.tagLocation.setVisibility(View.VISIBLE);
}
// 设置性别标签
if (!TextUtils.isEmpty(gender)) {
if (gender.contains("")) {
binding.tagGender.setText("");
} else if (gender.contains("")) {
binding.tagGender.setText("");
} else {
binding.tagGender.setText("H");
}
binding.tagGender.setVisibility(View.VISIBLE);
} else {
binding.tagGender.setText("H");
binding.tagGender.setVisibility(View.VISIBLE);
}
// 计算并设置年龄标签
if (!TextUtils.isEmpty(birthday)) {
int age = calculateAge(birthday);
if (age > 0) {
binding.tagAge.setText(age + "");
binding.tagAge.setVisibility(View.VISIBLE);
} else {
binding.tagAge.setVisibility(View.GONE);
}
} else {
binding.tagAge.setVisibility(View.GONE);
}
// 计算并设置星座标签
if (!TextUtils.isEmpty(birthday)) {
String constellation = calculateConstellation(birthday);
if (!TextUtils.isEmpty(constellation)) {
binding.tagConstellation.setText(constellation);
binding.tagConstellation.setVisibility(View.VISIBLE);
} else {
binding.tagConstellation.setVisibility(View.GONE);
}
} else {
binding.tagConstellation.setVisibility(View.GONE);
}
}
private void loadProfileInfo() {
String name = getSharedPreferences(PREFS_NAME, MODE_PRIVATE).getString(KEY_NAME, "爱你");
String location = getSharedPreferences(PREFS_NAME, MODE_PRIVATE).getString(KEY_LOCATION, "广西");
String bio = getSharedPreferences(PREFS_NAME, MODE_PRIVATE).getString(KEY_BIO, null);
if (binding.profileInfoLine1 != null) {
binding.profileInfoLine1.setText("昵称:" + name);
}
if (binding.profileInfoLine2 != null) {
String locationText = !TextUtils.isEmpty(location) ? location : "广西";
binding.profileInfoLine2.setText("地区:" + locationText);
}
if (binding.profileInfoLine3 != null) {
String bioText = (!TextUtils.isEmpty(bio) && !BIO_HINT_TEXT.equals(bio)) ? bio : "填写个人签名更容易获得关注";
binding.profileInfoLine3.setText("签名:" + bioText);
}
}
private int calculateAge(String birthdayStr) {
try {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());
Date birthDate = sdf.parse(birthdayStr);
if (birthDate == null) return 0;
Calendar birth = Calendar.getInstance();
birth.setTime(birthDate);
Calendar now = Calendar.getInstance();
int age = now.get(Calendar.YEAR) - birth.get(Calendar.YEAR);
if (now.get(Calendar.DAY_OF_YEAR) < birth.get(Calendar.DAY_OF_YEAR)) {
age--;
}
return age;
} catch (ParseException e) {
return 0;
}
}
private String calculateConstellation(String birthdayStr) {
try {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());
Date birthDate = sdf.parse(birthdayStr);
if (birthDate == null) return "";
Calendar cal = Calendar.getInstance();
cal.setTime(birthDate);
int month = cal.get(Calendar.MONTH) + 1; // Calendar.MONTH 从0开始
int day = cal.get(Calendar.DAY_OF_MONTH);
// 星座计算
if ((month == 3 && day >= 21) || (month == 4 && day <= 19)) {
return "白羊座";
} else if ((month == 4 && day >= 20) || (month == 5 && day <= 20)) {
return "金牛座";
} else if ((month == 5 && day >= 21) || (month == 6 && day <= 21)) {
return "双子座";
} else if ((month == 6 && day >= 22) || (month == 7 && day <= 22)) {
return "巨蟹座";
} else if ((month == 7 && day >= 23) || (month == 8 && day <= 22)) {
return "狮子座";
} else if ((month == 8 && day >= 23) || (month == 9 && day <= 22)) {
return "处女座";
} else if ((month == 9 && day >= 23) || (month == 10 && day <= 23)) {
return "天秤座";
} else if ((month == 10 && day >= 24) || (month == 11 && day <= 22)) {
return "天蝎座";
} else if ((month == 11 && day >= 23) || (month == 12 && day <= 21)) {
return "射手座";
} else if ((month == 12 && day >= 22) || (month == 1 && day <= 19)) {
return "摩羯座";
} else if ((month == 1 && day >= 20) || (month == 2 && day <= 18)) {
return "水瓶座";
} else if ((month == 2 && day >= 19) || (month == 3 && day <= 20)) {
return "双鱼座";
}
return "";
} catch (ParseException e) {
return "";
}
}
/**
* 显示更多选项菜单
*/
private void showMoreOptionsMenu() {
String[] options = {"黑名单管理", "设置", "关于"};
new androidx.appcompat.app.AlertDialog.Builder(this)
.setItems(options, (dialog, which) -> {
switch (which) {
case 0:
// 黑名单管理
if (!AuthHelper.requireLogin(this, "查看黑名单需要登录")) {
return;
}
BlacklistActivity.start(this);
break;
case 1:
// 设置
TabPlaceholderActivity.start(this, "设置");
break;
case 2:
// 关于
TabPlaceholderActivity.start(this, "关于");
break;
}
})
.show();
}
/**
* 显示分享个人主页对话框
*/
private void showShareProfileDialog() {
// 获取用户ID
String idText = binding.idLine.getText() != null ? binding.idLine.getText().toString() : "";
String digits = !TextUtils.isEmpty(idText) ? idText.replaceAll("\\D+", "") : "";
if (TextUtils.isEmpty(digits)) {
digits = "24187196"; // 默认ID
}
// 直接生成分享链接
String shareLink = ShareUtils.generateProfileShareLink(digits);
ShareUtils.shareLink(this, shareLink, "个人主页", "来看看我的主页吧");
}
/**
* 加载关注统计数据
*/
private void loadFollowStats() {
com.example.livestreaming.net.ApiService apiService =
com.example.livestreaming.net.ApiClient.getService(this);
retrofit2.Call<com.example.livestreaming.net.ApiResponse<java.util.Map<String, Object>>> call =
apiService.getFollowStats(null); // null表示查询当前用户
call.enqueue(new retrofit2.Callback<com.example.livestreaming.net.ApiResponse<java.util.Map<String, Object>>>() {
@Override
public void onResponse(retrofit2.Call<com.example.livestreaming.net.ApiResponse<java.util.Map<String, Object>>> call,
retrofit2.Response<com.example.livestreaming.net.ApiResponse<java.util.Map<String, Object>>> response) {
if (response.isSuccessful() && response.body() != null) {
com.example.livestreaming.net.ApiResponse<java.util.Map<String, Object>> apiResponse = response.body();
if (apiResponse.getCode() == 200 && apiResponse.getData() != null) {
java.util.Map<String, Object> stats = apiResponse.getData();
// 更新关注数
Object followingCount = stats.get("followingCount");
if (followingCount != null) {
int count = 0;
if (followingCount instanceof Number) {
count = ((Number) followingCount).intValue();
}
binding.following.setText(count + "\n关注");
// 更新快捷操作区域的关注数
android.widget.TextView followingCountText = findViewById(R.id.followingCount);
if (followingCountText != null) {
followingCountText.setText(count + "");
}
}
// 更新粉丝数
Object followersCount = stats.get("followersCount");
if (followersCount != null) {
int count = 0;
if (followersCount instanceof Number) {
count = ((Number) followersCount).intValue();
}
binding.followers.setText(count + "\n粉丝");
}
}
}
}
@Override
public void onFailure(retrofit2.Call<com.example.livestreaming.net.ApiResponse<java.util.Map<String, Object>>> call, Throwable t) {
// 忽略错误,使用默认显示
}
});
// 加载收藏数(点赞的直播间数量)
loadLikedRoomsCount();
// 加载好友数量
loadFriendsCount();
}
/**
* 加载好友数量
*/
private void loadFriendsCount() {
if (!AuthHelper.isLoggedIn(this)) {
return;
}
String token = com.example.livestreaming.net.AuthStore.getToken(this);
if (token == null) {
return;
}
String url = ApiConfig.getBaseUrl() + "/api/front/friends?page=1&pageSize=1";
okhttp3.OkHttpClient client = new okhttp3.OkHttpClient();
okhttp3.Request request = new okhttp3.Request.Builder()
.url(url)
.addHeader("Authori-zation", token)
.get()
.build();
client.newCall(request).enqueue(new okhttp3.Callback() {
@Override
public void onFailure(okhttp3.Call call, java.io.IOException e) {
// 忽略错误
}
@Override
public void onResponse(okhttp3.Call call, okhttp3.Response response) throws java.io.IOException {
String body = response.body() != null ? response.body().string() : "";
runOnUiThread(() -> {
try {
org.json.JSONObject json = new org.json.JSONObject(body);
if (json.optInt("code", -1) == 200) {
org.json.JSONObject data = json.optJSONObject("data");
if (data != null) {
long total = data.optLong("total", 0);
android.widget.TextView friendsCountText = findViewById(R.id.friendsCount);
if (friendsCountText != null) {
friendsCountText.setText(total + "");
}
}
}
} catch (Exception e) {
// 忽略解析错误
}
});
}
});
}
/**
* 加载收藏数(点赞的直播间数量)
*/
private void loadLikedRoomsCount() {
com.example.livestreaming.net.ApiService apiService =
com.example.livestreaming.net.ApiClient.getService(this);
retrofit2.Call<com.example.livestreaming.net.ApiResponse<com.example.livestreaming.net.PageResponse<java.util.Map<String, Object>>>> call =
apiService.getMyLikedRooms(1, 1); // 只获取第一页,用于获取总数
call.enqueue(new retrofit2.Callback<com.example.livestreaming.net.ApiResponse<com.example.livestreaming.net.PageResponse<java.util.Map<String, Object>>>>() {
@Override
public void onResponse(retrofit2.Call<com.example.livestreaming.net.ApiResponse<com.example.livestreaming.net.PageResponse<java.util.Map<String, Object>>>> call,
retrofit2.Response<com.example.livestreaming.net.ApiResponse<com.example.livestreaming.net.PageResponse<java.util.Map<String, Object>>>> response) {
if (response.isSuccessful() && response.body() != null) {
com.example.livestreaming.net.ApiResponse<com.example.livestreaming.net.PageResponse<java.util.Map<String, Object>>> apiResponse = response.body();
if (apiResponse.getCode() == 200 && apiResponse.getData() != null) {
com.example.livestreaming.net.PageResponse<java.util.Map<String, Object>> pageData = apiResponse.getData();
Long total = pageData.getTotal();
// 更新快捷操作区域的收藏数
android.widget.TextView likedRoomsCountText = findViewById(R.id.likedRoomsCount);
if (likedRoomsCountText != null) {
likedRoomsCountText.setText((total != null ? total : 0) + "个直播间");
}
}
}
}
@Override
public void onFailure(retrofit2.Call<com.example.livestreaming.net.ApiResponse<com.example.livestreaming.net.PageResponse<java.util.Map<String, Object>>>> call, Throwable t) {
// 忽略错误,使用默认显示
}
});
}
/**
* 加载钱包余额
*/
private void loadWalletBalance() {
if (!AuthHelper.isLoggedIn(this)) {
return;
}
ApiClient.getService(this).getVirtualBalance()
.enqueue(new Callback<ApiResponse<java.util.Map<String, Object>>>() {
@Override
public void onResponse(Call<ApiResponse<java.util.Map<String, Object>>> call,
Response<ApiResponse<java.util.Map<String, Object>>> response) {
if (response.isSuccessful() && response.body() != null && response.body().isOk()) {
java.util.Map<String, Object> data = response.body().getData();
if (data != null && data.containsKey("balance")) {
Object balanceObj = data.get("balance");
String balanceStr = "0";
if (balanceObj instanceof Number) {
double balance = ((Number) balanceObj).doubleValue();
// 如果是整数,不显示小数点
if (balance == Math.floor(balance)) {
balanceStr = String.valueOf((int) balance);
} else {
balanceStr = String.format("%.2f", balance);
}
} else if (balanceObj instanceof String) {
balanceStr = (String) balanceObj;
}
if (binding.walletBalance != null) {
binding.walletBalance.setText(balanceStr);
}
}
}
}
@Override
public void onFailure(Call<ApiResponse<java.util.Map<String, Object>>> call, Throwable t) {
// 忽略错误,使用默认显示
}
});
}
}