using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using Kill.Managers; using Kill.Network; using Kill.UI; 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; /// /// 未选中 选中 /// public Color[] textColors; private List _items = new List(); /// /// 确认回调:code 为选中的国家代码,null 表示返回/取消 /// public System.Action onConfirm; /// /// 初始化 /// /// 当前选中的国家代码 /// 是否显示返回按钮(主页不显示) 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(); 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(); } /// /// 返回按钮点击 /// private void OnBack() { onConfirm?.Invoke(null); } /// /// 滚动到当前选中的国家项(居中显示) /// 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(); 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); } /// /// 更新用户国家代码 /// private async System.Threading.Tasks.Task UpdateCountryCodeAsync(string code) { try { var requestData = new CountryCodeRequest { country_code = code }; var response = await NetworkCtrl.Instance.Put("/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}"); } } } 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(); _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