using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.UI; namespace JC.Unity.Picker { public class LocationPicker : MonoBehaviour, IDragHandler, IEndDragHandler { public enum LocationType { CountryRegion, State, City } /// /// 地区类型 /// public LocationType locationType; /// /// 子节点预制体 /// public GameObject _itemObj; /// /// 子节点容器对象 /// public Transform _itemParent; /// /// 我属于的地区选择组 /// [HideInInspector] public LocationPickerGroup myGroup; /// /// 最少节点数量 /// void Awake() { _itemObj.SetActive(false); } public void Init() { InitItems(); } void InitItems() { LocationInfo li = myGroup.selectLocation; ItemData itemData = SpawnItem(GetTopPosY(), li, GetLocationValue(li)); itemList.Add(itemData); MoveItems(0); CheckSelect(); } public void Refresh() { foreach (var item in itemList) { Destroy(item.obj); } itemList.Clear(); InitItems(); } float GetTopPosY() { return 0; } float GetBottomPosY() { return -myGroup.GetHeight(); } float _cellHeight = -1; float GetCellHeight() { if (_cellHeight == -1) _cellHeight = _itemObj.GetComponent().rect.height; return _cellHeight; } public void OnDrag(PointerEventData eventData) { MoveItems(eventData.delta.y); } void MoveItems(float dy) { foreach (var item in itemList) { item.SetY(dy, true); } while (itemList[0].GetY() < GetTopPosY()) { ItemData compareItemData = itemList[0]; LocationInfo li = ChangeLocation(compareItemData.locationInfo, -1); if (!li.IsValid()) { break; } ItemData itemData = SpawnItem(compareItemData.GetY() + GetCellHeight(), li, GetLocationValue(li)); itemList.Insert(0, itemData); } while (itemList.Count > 1 && itemList[0].GetY() > GetTopPosY() + GetCellHeight()) { Destroy(itemList[0].obj); itemList.RemoveAt(0); } while (itemList[itemList.Count - 1].GetY() > GetBottomPosY()) { ItemData compareItemData = itemList[itemList.Count - 1]; LocationInfo li = ChangeLocation(compareItemData.locationInfo, +1); if (!li.IsValid()) { break; } ItemData itemData = SpawnItem(compareItemData.GetY() - GetCellHeight(), li, GetLocationValue(li)); itemList.Add(itemData); } while (itemList.Count > 1 && itemList[itemList.Count - 1].GetY() < GetBottomPosY()) { Destroy(itemList[itemList.Count - 1].obj); itemList.RemoveAt(itemList.Count - 1); } } public void OnEndDrag(PointerEventData eventData) { CheckSelect(); myGroup.onDateUpdate(); } void CheckSelect() { float dy = 0; float minDist = float.MaxValue; ItemData targetItem = null; foreach (var item in itemList) { item.SetSelected(false); float val = item.GetY() - 0; float absVal = Mathf.Abs(val); if (absVal < minDist) { //选中最符合的节点 minDist = absVal; targetItem = item; dy = val; } } if (dy != 0) { MoveItems(-dy); } targetItem.SetSelected(true); myGroup.selectLocation = targetItem.locationInfo; } LocationInfo ChangeLocation(LocationInfo locationInfo, int num) { switch (locationType) { case LocationType.CountryRegion: locationInfo = locationInfo.ChangeCountryRegionIndex(num); break; case LocationType.State: locationInfo = locationInfo.ChangeStateIndex(num); break; case LocationType.City: locationInfo = locationInfo.ChangeCityIndex(num); break; } return locationInfo; } string GetLocationValue(LocationInfo locationInfo) { switch (locationType) { case LocationType.CountryRegion: return locationInfo.GetCountryRegion().Item1; case LocationType.State: return locationInfo.GetState().Item1; case LocationType.City: return locationInfo.GetCity().Item1; } throw new Exception("GetDateValue Error"); } public class ItemData { public GameObject obj; public LocationInfo locationInfo; public bool selected = false; public float GetY() { return obj.GetComponent().localPosition.y; } public void SetY(float y, bool plus = false) { RectTransform rectTF = obj.GetComponent(); Vector3 pos = rectTF.localPosition; if (plus) { pos.y += y; } else { pos.y = y; } rectTF.localPosition = pos; } public void SetText(string text) { obj.GetComponent().text = text; } public void SetColor(Color color) { obj.GetComponent().color = color; } public void SetSelected(bool val) { selected = val; SetColor(selected ? Color.green : Color.grey); } } List itemList = new List(); ItemData SpawnItem(float y, LocationInfo locationInfo, string text) { ItemData itemData = new ItemData(); itemData.locationInfo = locationInfo; itemData.obj = Instantiate(_itemObj, _itemParent); itemData.SetY(y); itemData.SetText(text); itemData.SetSelected(false); itemData.obj.SetActive(true); return itemData; } } }