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 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, FishPondActivity.class)); finish(); return true; } if (id == R.id.nav_wish_tree) { WishTreeActivity.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对象应包含: 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>() { @Override public void onResponse(Call> call, Response> 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> 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 // 更新成功后,同步更新本地缓存和界面显示 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; } WatchHistoryActivity.start(this); }); binding.topActionMore.setOnClickListener(v -> TabPlaceholderActivity.start(this, "更多")); 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.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); }); } 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对象应包含: 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> // 实现步骤: // 1. 从AuthStore获取token,解析userId(或从用户信息中获取) // 2. 调用接口获取作品列表 // 3. 更新UI显示作品列表或空状态 // 4. 处理错误情况(网络错误、未登录等) // 注意: 此方法在onResume时也会调用,需要避免重复请求 // 临时:从本地存储加载(等待后端接口) List 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> // WorkItem对象应包含: id, title, coverUrl, likeCount, viewCount, publishTime等字段 // TODO: 接入后端接口 - 获取用户收藏列表 // 接口路径: GET /api/users/{userId}/favorites // 请求参数: // - userId: 用户ID(从token中获取) // - page (可选): 页码 // - pageSize (可选): 每页数量 // 返回数据格式: ApiResponse> // TODO: 接入后端接口 - 获取用户赞过的作品列表 // 接口路径: GET /api/users/{userId}/liked // 请求参数: // - userId: 用户ID(从token中获取) // - page (可选): 页码 // - pageSize (可选): 每页数量 // 返回数据格式: ApiResponse> // 标签页顺序: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(); // 刷新关注统计 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>>() { @Override public void onResponse(Call>> call, Response>> response) { if (!response.isSuccessful() || response.body() == null) { // 接口调用失败,隐藏按钮 if (binding.streamerCenterBtn != null) { binding.streamerCenterBtn.setVisibility(View.GONE); } return; } ApiResponse> body = response.body(); if (body.getCode() != 200 || body.getData() == null) { // 接口返回错误,隐藏按钮 if (binding.streamerCenterBtn != null) { binding.streamerCenterBtn.setVisibility(View.GONE); } return; } java.util.Map 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>> 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 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>> call = apiService.getFollowStats(null); // null表示查询当前用户 call.enqueue(new retrofit2.Callback>>() { @Override public void onResponse(retrofit2.Call>> call, retrofit2.Response>> response) { if (response.isSuccessful() && response.body() != null) { com.example.livestreaming.net.ApiResponse> apiResponse = response.body(); if (apiResponse.getCode() == 200 && apiResponse.getData() != null) { java.util.Map 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>> call, Throwable t) { // 忽略错误,使用默认显示 } }); // 加载收藏数(点赞的直播间数量) loadLikedRoomsCount(); } /** * 加载收藏数(点赞的直播间数量) */ private void loadLikedRoomsCount() { com.example.livestreaming.net.ApiService apiService = com.example.livestreaming.net.ApiClient.getService(this); retrofit2.Call>>> call = apiService.getMyLikedRooms(1, 1); // 只获取第一页,用于获取总数 call.enqueue(new retrofit2.Callback>>>() { @Override public void onResponse(retrofit2.Call>>> call, retrofit2.Response>>> response) { if (response.isSuccessful() && response.body() != null) { com.example.livestreaming.net.ApiResponse>> apiResponse = response.body(); if (apiResponse.getCode() == 200 && apiResponse.getData() != null) { com.example.livestreaming.net.PageResponse> pageData = apiResponse.getData(); int total = pageData.getTotal(); // 更新快捷操作区域的收藏数 android.widget.TextView likedRoomsCountText = findViewById(R.id.likedRoomsCount); if (likedRoomsCountText != null) { likedRoomsCountText.setText(total + "个直播间"); } } } } @Override public void onFailure(retrofit2.Call>>> call, Throwable t) { // 忽略错误,使用默认显示 } }); } }