LocationPicker.cs 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using UnityEngine;
  5. using UnityEngine.EventSystems;
  6. using UnityEngine.UI;
  7. namespace JC.Unity.Picker {
  8. public class LocationPicker : MonoBehaviour, IDragHandler, IEndDragHandler
  9. {
  10. public enum LocationType {
  11. CountryRegion, State, City
  12. }
  13. /// <summary>
  14. /// 地区类型
  15. /// </summary>
  16. public LocationType locationType;
  17. /// <summary>
  18. /// 子节点预制体
  19. /// </summary>
  20. public GameObject _itemObj;
  21. /// <summary>
  22. /// 子节点容器对象
  23. /// </summary>
  24. public Transform _itemParent;
  25. /// <summary>
  26. /// 我属于的地区选择组
  27. /// </summary>
  28. [HideInInspector]
  29. public LocationPickerGroup myGroup;
  30. /// <summary>
  31. /// 最少节点数量
  32. /// </summary>
  33. void Awake()
  34. {
  35. _itemObj.SetActive(false);
  36. }
  37. public void Init() {
  38. InitItems();
  39. }
  40. void InitItems() {
  41. LocationInfo li = myGroup.selectLocation;
  42. ItemData itemData = SpawnItem(GetTopPosY(), li, GetLocationValue(li));
  43. itemList.Add(itemData);
  44. MoveItems(0);
  45. CheckSelect();
  46. }
  47. public void Refresh() {
  48. foreach (var item in itemList) {
  49. Destroy(item.obj);
  50. }
  51. itemList.Clear();
  52. InitItems();
  53. }
  54. float GetTopPosY() {
  55. return 0;
  56. }
  57. float GetBottomPosY() {
  58. return -myGroup.GetHeight();
  59. }
  60. float _cellHeight = -1;
  61. float GetCellHeight() {
  62. if (_cellHeight == -1) _cellHeight = _itemObj.GetComponent<RectTransform>().rect.height;
  63. return _cellHeight;
  64. }
  65. public void OnDrag(PointerEventData eventData) {
  66. MoveItems(eventData.delta.y);
  67. }
  68. void MoveItems(float dy) {
  69. foreach (var item in itemList) {
  70. item.SetY(dy, true);
  71. }
  72. while (itemList[0].GetY() < GetTopPosY()) {
  73. ItemData compareItemData = itemList[0];
  74. LocationInfo li = ChangeLocation(compareItemData.locationInfo, -1);
  75. if (!li.IsValid()) {
  76. break;
  77. }
  78. ItemData itemData = SpawnItem(compareItemData.GetY() + GetCellHeight(), li, GetLocationValue(li));
  79. itemList.Insert(0, itemData);
  80. }
  81. while (itemList.Count > 1 && itemList[0].GetY() > GetTopPosY() + GetCellHeight()) {
  82. Destroy(itemList[0].obj);
  83. itemList.RemoveAt(0);
  84. }
  85. while (itemList[itemList.Count - 1].GetY() > GetBottomPosY()) {
  86. ItemData compareItemData = itemList[itemList.Count - 1];
  87. LocationInfo li = ChangeLocation(compareItemData.locationInfo, +1);
  88. if (!li.IsValid()) {
  89. break;
  90. }
  91. ItemData itemData = SpawnItem(compareItemData.GetY() - GetCellHeight(), li, GetLocationValue(li));
  92. itemList.Add(itemData);
  93. }
  94. while (itemList.Count > 1 && itemList[itemList.Count - 1].GetY() < GetBottomPosY()) {
  95. Destroy(itemList[itemList.Count - 1].obj);
  96. itemList.RemoveAt(itemList.Count - 1);
  97. }
  98. }
  99. public void OnEndDrag(PointerEventData eventData)
  100. {
  101. CheckSelect();
  102. myGroup.onDateUpdate();
  103. }
  104. void CheckSelect() {
  105. float dy = 0;
  106. float minDist = float.MaxValue;
  107. ItemData targetItem = null;
  108. foreach (var item in itemList) {
  109. item.SetSelected(false);
  110. float val = item.GetY() - 0;
  111. float absVal = Mathf.Abs(val);
  112. if (absVal < minDist) { //选中最符合的节点
  113. minDist = absVal;
  114. targetItem = item;
  115. dy = val;
  116. }
  117. }
  118. if (dy != 0) {
  119. MoveItems(-dy);
  120. }
  121. targetItem.SetSelected(true);
  122. myGroup.selectLocation = targetItem.locationInfo;
  123. }
  124. LocationInfo ChangeLocation(LocationInfo locationInfo, int num) {
  125. switch (locationType) {
  126. case LocationType.CountryRegion:
  127. locationInfo = locationInfo.ChangeCountryRegionIndex(num);
  128. break;
  129. case LocationType.State:
  130. locationInfo = locationInfo.ChangeStateIndex(num);
  131. break;
  132. case LocationType.City:
  133. locationInfo = locationInfo.ChangeCityIndex(num);
  134. break;
  135. }
  136. return locationInfo;
  137. }
  138. string GetLocationValue(LocationInfo locationInfo) {
  139. switch (locationType) {
  140. case LocationType.CountryRegion:
  141. return locationInfo.GetCountryRegion().Item1;
  142. case LocationType.State:
  143. return locationInfo.GetState().Item1;
  144. case LocationType.City:
  145. return locationInfo.GetCity().Item1;
  146. }
  147. throw new Exception("GetDateValue Error");
  148. }
  149. public class ItemData {
  150. public GameObject obj;
  151. public LocationInfo locationInfo;
  152. public bool selected = false;
  153. public float GetY() {
  154. return obj.GetComponent<RectTransform>().localPosition.y;
  155. }
  156. public void SetY(float y, bool plus = false) {
  157. RectTransform rectTF = obj.GetComponent<RectTransform>();
  158. Vector3 pos = rectTF.localPosition;
  159. if (plus) {
  160. pos.y += y;
  161. } else {
  162. pos.y = y;
  163. }
  164. rectTF.localPosition = pos;
  165. }
  166. public void SetText(string text) {
  167. obj.GetComponent<Text>().text = text;
  168. }
  169. public void SetColor(Color color) {
  170. obj.GetComponent<Text>().color = color;
  171. }
  172. public void SetSelected(bool val) {
  173. selected = val;
  174. SetColor(selected ? Color.green : Color.grey);
  175. }
  176. }
  177. List<ItemData> itemList = new List<ItemData>();
  178. ItemData SpawnItem(float y, LocationInfo locationInfo, string text) {
  179. ItemData itemData = new ItemData();
  180. itemData.locationInfo = locationInfo;
  181. itemData.obj = Instantiate(_itemObj, _itemParent);
  182. itemData.SetY(y);
  183. itemData.SetText(text);
  184. itemData.SetSelected(false);
  185. itemData.obj.SetActive(true);
  186. return itemData;
  187. }
  188. }
  189. }