标签:
1 ////////////////////////////////////////////////////////////////////////// 2 // 乐探游戏版权所有 3 // 4 // 作者:THW 5 // 时间:2015/07/11 6 // 描述:自定义UITable 7 // 说明:主要用于多行多列的ScrollView 8 // 9 ////////////////////////////////////////////////////////////////////////// 10 11 using UnityEngine; 12 using System.Collections.Generic; 13 14 public class CustomUITable : UIWidgetContainer 15 { 16 public float cellWidth = 200f; 17 public float cellHeight = 200f; 18 19 private UIScrollView mScrollView; 20 private UIPanel mPanel; 21 private GameObject itemPrefab; 22 23 private List<CustomSVItemData> m_DataList; // 当前Grid要显示的数据集合 24 private CustomSVItemBaseMono[] m_itemList; // 当前Grid要显示的Item最大数量集合 25 private Vector3 defaultVec; 26 private float lastY = -1; 27 private int maxRow; // 最多能显示的总行数 28 private int maxCol; // 最多能显示的总列数 29 private int maxItemNum; // 最多能显示的Item数量 30 private float mSpace; // 每个Item的间距 31 private bool mInitDone; 32 private bool mRepositionNow; 33 34 /// <summary> 35 /// Init 必须在LateUpdate中执行 36 /// </summary> 37 public void Init() 38 { 39 if (mPanel == null || mScrollView == null || itemPrefab == null) 40 return; 41 42 mInitDone = true; 43 44 Vector2 viewSize = mPanel.GetViewSize(); // 这个值必须在LateUpdate中才能获得 45 46 // 得到总列数 47 maxCol = Mathf.Max(1, (int)(viewSize.x / cellWidth)); 48 mSpace = maxCol > 1 ? (viewSize.x - cellWidth * maxCol) / (maxCol + 1) : 0; 49 50 // 得到总行数 51 maxRow = Mathf.CeilToInt(viewSize.y / (cellHeight + mSpace)) + 1; 52 53 maxItemNum = maxCol * maxRow; 54 55 m_itemList = new CustomSVItemBaseMono[maxItemNum]; 56 57 // 预先创建Item 58 CreateItem(); 59 } 60 61 public void Awake() 62 { 63 mPanel = NGUITools.FindInParents<UIPanel>(gameObject); 64 mScrollView = NGUITools.FindInParents<UIScrollView>(gameObject); 65 itemPrefab = transform.FindChild("Item").gameObject; 66 67 defaultVec = new Vector3(0, cellHeight, 0); 68 m_DataList = new List<CustomSVItemData>(); 69 } 70 71 public void Start() 72 { 73 74 } 75 76 public void LateUpdate() 77 { 78 if (!mInitDone) 79 { 80 Init(); 81 } 82 } 83 84 /// <summary> 85 /// 重新排版——每次Item数量有变动的时候,需要调用 86 /// </summary> 87 public bool repositionNow 88 { 89 set 90 { 91 mRepositionNow = value; 92 } 93 } 94 95 public void AddItem(CustomSVItemData data) 96 { 97 m_DataList.Add(data); 98 mRepositionNow = true; 99 } 100 101 public void AddItems(List<CustomSVItemData> dataList) 102 { 103 m_DataList.AddRange(dataList); 104 mRepositionNow = true; 105 } 106 107 public void RemoveItem(CustomSVItemData data) 108 { 109 m_DataList.Remove(data); 110 mRepositionNow = true; 111 } 112 113 public void Clear() 114 { 115 m_DataList.Clear(); 116 mRepositionNow = true; 117 } 118 119 protected virtual void Update() 120 { 121 if (!mInitDone) 122 return; 123 124 if (Mathf.Abs(mScrollView.transform.localPosition.y - lastY) > cellHeight * 0.5 || mRepositionNow) 125 { 126 Validate(); 127 lastY = mScrollView.transform.localPosition.y; 128 } 129 } 130 131 private void ConstrainWithinPanel() 132 { 133 if (mPanel != null) 134 { 135 mPanel.ConstrainTargetToBounds(transform, true); 136 mScrollView.UpdateScrollbars(true); 137 mScrollView.RestrictWithinBounds(true); 138 } 139 } 140 141 private void Validate() 142 { 143 if (!mInitDone) 144 return; 145 146 mRepositionNow = false; 147 148 Vector3 position = mPanel.transform.localPosition; 149 float _ver = Mathf.Max(position.y, 0); 150 151 int startRowIndex = Mathf.FloorToInt(_ver / (cellHeight + mSpace)); // 当前要显示的行 152 153 int startIndex = startRowIndex * maxCol; // 开始显示数据的索引 154 int endIndex = Mathf.Min(m_DataList.Count, startIndex + maxItemNum); // 最大显示数据的索引 155 int curCol = 0; 156 int curRow = startRowIndex; 157 int curIndex = 0; 158 for (int i = startIndex; i < startIndex + maxItemNum; i++) 159 { 160 CustomSVItemBaseMono item = m_itemList[curIndex]; 161 Vector3 pos = item.transform.localPosition; 162 float depth = pos.z; 163 164 if (i < endIndex) 165 { 166 item.mData = m_DataList[i]; 167 pos = new Vector3(cellWidth * curCol + (curCol + 1) * mSpace, -cellHeight * curRow - (curRow + 1) * mSpace, depth); 168 item.gameObject.SetActive(true); 169 } 170 else 171 { 172 pos = defaultVec; 173 } 174 item.transform.localPosition = pos; 175 176 if (++curCol >= maxCol) 177 { 178 curCol = 0; 179 ++curRow; 180 } 181 ++curIndex; 182 } 183 } 184 185 private void CreateItem() 186 { 187 for (int i = 0; i < maxItemNum; i++) 188 { 189 GameObject go = Instantiate(itemPrefab) as GameObject; 190 go.transform.parent = transform; 191 go.transform.localScale = Vector3.one; 192 go.SetActive(false); 193 go.name = "Item" + i; 194 CustomSVItemBaseMono item = go.GetComponent<CustomSVItemBaseMono>(); 195 item.Init(); 196 m_itemList[i] = item; 197 } 198 } 199 }
1 ////////////////////////////////////////////////////////////////////////// 2 // 乐探游戏版权所有 3 // 4 // 作者:THW 5 // 时间:2015/07/11 6 // 描述:Scroll view 的 Item 基类 7 // 说明:其他Item类必须继承此基类 8 // 9 ////////////////////////////////////////////////////////////////////////// 10 11 using UnityEngine; 12 using System.Collections; 13 14 public class CustomSVItemBaseMono : MonoBehaviour 15 { 16 protected CustomSVItemData m_Data; 17 18 public virtual bool Init() 19 { 20 return true; 21 } 22 23 public CustomSVItemData mData 24 { 25 set 26 { 27 m_Data = value; 28 OnChange(); 29 } 30 get 31 { 32 return m_Data; 33 } 34 } 35 36 protected virtual void OnChange() 37 { 38 } 39 40 private virtual void Update() 41 { 42 if (m_Data.bRefresh) 43 { 44 m_Data.bRefresh = false; 45 OnChange(); 46 } 47 } 48 } 49 50 /// <summary> 51 /// 自定义Scroll view item 的数据内容 52 /// </summary> 53 public class CustomSVItemData 54 { 55 public bool bRefresh; // 是否要刷新Item 56 }
标签:
原文地址:http://www.cnblogs.com/cocos2d/p/4643126.html