killapp/Assets/Scripts/UI/Components/SelectCountry.cs
“虞渠成” 146938ef95 feat: 新增资源、更新页面功能与资源配置
1. 新增两张UI纹理图片并配置导入参数
2. 更新个人中心重置密码面板注释
3. 为国家选择组件添加加载弹窗显示隐藏逻辑
4. 简化注册设置密码面板的冗余代码
5. 更新主场景资源位置配置
6. 替换个人中心密码页的UI精灵资源
7. 优化资源更新逻辑,添加内存bundle缓存清理与调试日志
2026-07-29 09:31:30 +08:00

254 lines
7.6 KiB
C#
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.

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using Kill.Managers;
using Kill.Network;
using Kill.UI;
using Kill.UI.Components;
public class SelectCountry : MonoBehaviour
{
public GameObject countryPrefab;
public Transform countryParent;
public Button submitButton;
public Button backButton;
public InputField searchInput;
public ScrollRect scrollRect;
LanguageManager.Country selectCountry;
private bool _hasSelection;
private string _originalCode;
/// <summary>
/// 未选中 选中
/// </summary>
public Color[] textColors;
private List<SelectCountryItem> _items = new List<SelectCountryItem>();
/// <summary>
/// 确认回调code 为选中的国家代码null 表示返回/取消
/// </summary>
public System.Action<string> onConfirm;
/// <summary>
/// 初始化
/// </summary>
/// <param name="code">当前选中的国家代码</param>
/// <param name="showBackButton">是否显示返回按钮(主页不显示)</param>
public void Init(string code, bool showBackButton = true)
{
_originalCode = code;
countryPrefab.SetActive(false);
// 清理旧 item
foreach (var item in _items)
Destroy(item.gameObject);
_items.Clear();
_hasSelection = false;
// 返回按钮
if (backButton != null)
{
backButton.gameObject.SetActive(showBackButton);
backButton.onClick.RemoveAllListeners();
backButton.onClick.AddListener(OnBack);
if (showBackButton)
UIManager.Instance.RegisterBackAction(OnBack);
}
if (LanguageManager.Instance == null || LanguageManager.Instance.countryList == null)
return;
foreach (var country in LanguageManager.Instance.countryList)
{
var go = Instantiate(countryPrefab, countryParent);
var item = go.AddComponent<SelectCountryItem>();
item.Init(this, country);
_items.Add(item);
item.gameObject.SetActive(true);
}
// 绑定搜索
if (searchInput != null)
{
searchInput.onValueChanged.RemoveAllListeners();
searchInput.onValueChanged.AddListener(OnSearchChanged);
}
// 设置默认选中code 为空时不选中)
if (!string.IsNullOrEmpty(code))
SelectCountryByCode(code);
// 自动滚动到选中项
ScrollToSelected();
UpdateSubmitButton();
}
/// <summary>
/// 返回按钮点击
/// </summary>
private void OnBack()
{
onConfirm?.Invoke(null);
}
/// <summary>
/// 滚动到当前选中的国家项(居中显示)
/// </summary>
private void ScrollToSelected()
{
if (scrollRect == null || !_hasSelection) return;
int index = _items.FindIndex(i => i.Country.code == selectCountry.code);
if (index < 0) return;
Canvas.ForceUpdateCanvases();
var itemRect = _items[index].GetComponent<RectTransform>();
float contentHeight = scrollRect.content.rect.height;
float viewportHeight = scrollRect.viewport.rect.height;
if (contentHeight <= viewportHeight) return;
// 计算目标滚动位置:使选中项居中
float maxScrollY = contentHeight - viewportHeight;
float itemCenterY = Mathf.Abs(itemRect.anchoredPosition.y) + itemRect.rect.height / 2;
float targetScrollY = itemCenterY - viewportHeight / 2;
targetScrollY = Mathf.Clamp(targetScrollY, 0, maxScrollY);
scrollRect.verticalNormalizedPosition = 1f - targetScrollY / maxScrollY;
}
private void OnSearchChanged(string keyword)
{
foreach (var item in _items)
{
item.gameObject.SetActive(item.MatchKeyword(keyword));
}
}
public void SelectCountryByCode(string code)
{
_hasSelection = !string.IsNullOrEmpty(code);
foreach (var item in _items)
{
bool isSelected = _hasSelection && item.Country.code == code;
item.SetSelected(isSelected);
if (isSelected)
selectCountry = item.Country;
}
UpdateSubmitButton();
}
public string GetSelectedCode()
{
return _hasSelection ? selectCountry.code : null;
}
private void UpdateSubmitButton()
{
if (submitButton != null)
{
submitButton.gameObject.SetActive(_hasSelection);
submitButton.onClick.RemoveAllListeners();
submitButton.onClick.AddListener(OnSubmit);
}
}
private async void OnSubmit()
{
if (!_hasSelection) return;
await UpdateCountryCodeAsync(selectCountry.code);
}
/// <summary>
/// 更新用户国家代码
/// </summary>
private async System.Threading.Tasks.Task UpdateCountryCodeAsync(string code)
{
LoadingUI.Show();
try
{
var requestData = new CountryCodeRequest
{
country_code = code
};
var response = await NetworkCtrl.Instance.Put<NoDataResponse>("/api/v1/user/country-code", requestData);
ResponseCodeHandler.HandleResponse(response,
onSuccess: (data) =>
{
if (DataManager.Instance.userInfo != null)
DataManager.Instance.userInfo.country_code = code;
onConfirm?.Invoke(code);
},
onError: null
);
}
catch (Exception ex)
{
Debug.LogError($"更新国家代码失败: {ex.Message}");
}
LoadingUI.Hide();
}
}
internal class SelectCountryItem : MonoBehaviour
{
public LanguageManager.Country Country { get; private set; }
private SelectCountry _parent;
private Text _nameText;
private GameObject _selectGo;
private Color _selectedColor;
private Color _unselectedColor;
public void Init(SelectCountry parent, LanguageManager.Country country)
{
_parent = parent;
Country = country;
_nameText = transform.Find("name")?.GetComponent<Text>();
_selectGo = transform.Find("选中")?.gameObject;
_selectedColor = parent.textColors.Length > 0 ? parent.textColors[0] : Color.white;
_unselectedColor = parent.textColors.Length > 1 ? parent.textColors[1] : Color.gray;
// 显示国家名称(根据当前语言)
bool isChinese = LanguageManager.Instance != null && LanguageManager.Instance.languageType == LanguageManager.LanguageType.Chinese;
if (_nameText != null)
_nameText.text = isChinese ? country.name_zh : country.name_en;
// 点击事件
var btn = GetComponent<Button>();
if (btn == null)
btn = gameObject.AddComponent<Button>();
btn.onClick.AddListener(OnClick);
}
public void SetSelected(bool selected)
{
if (_nameText != null)
_nameText.color = selected ? _selectedColor : _unselectedColor;
if (_selectGo != null)
_selectGo.SetActive(selected);
}
public bool MatchKeyword(string keyword)
{
if (string.IsNullOrEmpty(keyword))
return true;
var k = keyword.ToLower();
return Country.name_zh.ToLower().Contains(k)
|| Country.name_en.ToLower().Contains(k)
|| Country.code.ToLower().Contains(k);
}
private void OnClick()
{
_parent.SelectCountryByCode(Country.code);
}
}