├── .gitignore ├── Assets ├── Test │ ├── test.unity │ ├── ListItem.prefab │ ├── DiffSizeListItem.prefab │ ├── test.unity.meta │ ├── ListItem.prefab.meta │ ├── DiffSizeListItem.prefab.meta │ ├── TestListView.cs.meta │ ├── TestListItemView.cs.meta │ ├── TestDiffsizeListItemView.cs.meta │ ├── TestListItemView.cs │ ├── TestDiffsizeListItemView.cs │ └── TestListView.cs ├── Test.meta ├── Standard Assets.meta └── Standard Assets │ ├── UListView.meta │ └── UListView │ ├── IUListView.cs.meta │ ├── IUListItemView.cs.meta │ ├── UGridListView.cs.meta │ ├── USimpleListView.cs.meta │ ├── USimpleDiffSizeListView.cs.meta │ ├── IUListItemView.cs │ ├── USimpleListView.cs │ ├── UGridListView.cs │ ├── USimpleDiffSizeListView.cs │ └── IUListView.cs ├── ProjectSettings ├── TagManager.asset ├── AudioManager.asset ├── InputManager.asset ├── NavMeshLayers.asset ├── TimeManager.asset ├── DynamicsManager.asset ├── EditorSettings.asset ├── NetworkManager.asset ├── ProjectSettings.asset ├── QualitySettings.asset ├── GraphicsSettings.asset ├── Physics2DSettings.asset └── EditorBuildSettings.asset └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | Library/* 2 | Temp/* 3 | *.csproj 4 | *.sln 5 | *.suo 6 | *.userprefs 7 | obj/* 8 | -------------------------------------------------------------------------------- /Assets/Test/test.unity: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tnqiang/Unity_ListView/HEAD/Assets/Test/test.unity -------------------------------------------------------------------------------- /Assets/Test/ListItem.prefab: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tnqiang/Unity_ListView/HEAD/Assets/Test/ListItem.prefab -------------------------------------------------------------------------------- /ProjectSettings/TagManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tnqiang/Unity_ListView/HEAD/ProjectSettings/TagManager.asset -------------------------------------------------------------------------------- /Assets/Test/DiffSizeListItem.prefab: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tnqiang/Unity_ListView/HEAD/Assets/Test/DiffSizeListItem.prefab -------------------------------------------------------------------------------- /ProjectSettings/AudioManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tnqiang/Unity_ListView/HEAD/ProjectSettings/AudioManager.asset -------------------------------------------------------------------------------- /ProjectSettings/InputManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tnqiang/Unity_ListView/HEAD/ProjectSettings/InputManager.asset -------------------------------------------------------------------------------- /ProjectSettings/NavMeshLayers.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tnqiang/Unity_ListView/HEAD/ProjectSettings/NavMeshLayers.asset -------------------------------------------------------------------------------- /ProjectSettings/TimeManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tnqiang/Unity_ListView/HEAD/ProjectSettings/TimeManager.asset -------------------------------------------------------------------------------- /Assets/Test/test.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 60f4c6e1b3bdae542b8cc8bc3023d3ba 3 | DefaultImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /ProjectSettings/DynamicsManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tnqiang/Unity_ListView/HEAD/ProjectSettings/DynamicsManager.asset -------------------------------------------------------------------------------- /ProjectSettings/EditorSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tnqiang/Unity_ListView/HEAD/ProjectSettings/EditorSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/NetworkManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tnqiang/Unity_ListView/HEAD/ProjectSettings/NetworkManager.asset -------------------------------------------------------------------------------- /ProjectSettings/ProjectSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tnqiang/Unity_ListView/HEAD/ProjectSettings/ProjectSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/QualitySettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tnqiang/Unity_ListView/HEAD/ProjectSettings/QualitySettings.asset -------------------------------------------------------------------------------- /ProjectSettings/GraphicsSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tnqiang/Unity_ListView/HEAD/ProjectSettings/GraphicsSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/Physics2DSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tnqiang/Unity_ListView/HEAD/ProjectSettings/Physics2DSettings.asset -------------------------------------------------------------------------------- /Assets/Test.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b007382d1d244ef4784768ab699ce6e0 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /Assets/Test/ListItem.prefab.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5a1b7ec36a3e4e74b8fd44beec19d0d1 3 | NativeFormatImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /ProjectSettings/EditorBuildSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tnqiang/Unity_ListView/HEAD/ProjectSettings/EditorBuildSettings.asset -------------------------------------------------------------------------------- /Assets/Test/DiffSizeListItem.prefab.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 42aef965dad688042aa3a251801e2b0a 3 | NativeFormatImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Assets/Standard Assets.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1f5870fb379b6404c89ae87ae661d757 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /Assets/Standard Assets/UListView.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 23cc752f103c9e5498fbf38e099a840b 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /Assets/Test/TestListView.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 88fdfb78fd3e334469f5d88cc96c648f 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Test/TestListItemView.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e889580eafa16454693c0ebf89d48b90 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Test/TestDiffsizeListItemView.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f951eeadc46088d41945ac9d42a03a32 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Standard Assets/UListView/IUListView.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9ae8de1b1caa97946adbe80bac00ca8b 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Standard Assets/UListView/IUListItemView.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7154f326cfb2c9f438407c4266db117b 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Standard Assets/UListView/UGridListView.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5199d92bbd527ef489d44e93bba3f89a 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Standard Assets/UListView/USimpleListView.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d24f16bdc700010488366ad71a3cbb4b 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Standard Assets/UListView/USimpleDiffSizeListView.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 36c0fbf46bc6ac64fb9e01db5d2f4afe 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Test/TestListItemView.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEngine.UI; 3 | using System.Collections; 4 | using NSUListView; 5 | 6 | public class TestListItemView : IUListItemView { 7 | public Text text; 8 | public override void SetData(object data) 9 | { 10 | int num = (int)data; 11 | text.text = num.ToString (); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Assets/Standard Assets/UListView/IUListItemView.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEngine.UI; 3 | 4 | namespace NSUListView 5 | { 6 | public abstract class IUListItemView : MonoBehaviour 7 | { 8 | RectTransform rectTransform; 9 | 10 | public abstract void SetData(object data); 11 | 12 | public virtual Vector2 GetItemSize(object data) 13 | { 14 | if (null == rectTransform) 15 | { 16 | rectTransform = transform as RectTransform; 17 | } 18 | return rectTransform.rect.size; 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /Assets/Test/TestDiffsizeListItemView.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEngine.UI; 3 | using System.Collections; 4 | using NSUListView; 5 | 6 | public class TestDiffsizeListItemView : IUListItemView { 7 | public Text text; 8 | RectTransform rectTrans = null; 9 | 10 | public override void SetData(object data) 11 | { 12 | int num = (int)data; 13 | text.text = num.ToString (); 14 | if (null == rectTrans) 15 | { 16 | rectTrans = transform as RectTransform; 17 | } 18 | Vector2 rect = rectTrans.sizeDelta; 19 | rect.y = 100 + num; 20 | rectTrans.sizeDelta = rect; 21 | } 22 | 23 | public override Vector2 GetItemSize (object data) 24 | { 25 | int num = (int)data; 26 | Vector2 rect = new Vector2 (100, 100); 27 | rect.y += num; 28 | return rect; 29 | } 30 | } -------------------------------------------------------------------------------- /Assets/Test/TestListView.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using NSUListView; 5 | 6 | public class TestListView : MonoBehaviour 7 | { 8 | public IUListView listView; 9 | 10 | void Start() 11 | { 12 | List lstData = new List (); 13 | for (int i=0; i<100; ++i) { 14 | lstData.Add (i); 15 | } 16 | listView.SetData (lstData); 17 | StartCoroutine (DecreateCoroutine ()); 18 | StartCoroutine (DecreateCoroutine2 ()); 19 | } 20 | 21 | IEnumerator DecreateCoroutine() 22 | { 23 | yield return new WaitForSeconds(5); 24 | List lstData = new List (); 25 | for (int i=0; i<10; ++i) { 26 | lstData.Add (i); 27 | } 28 | listView.SetData (lstData); 29 | } 30 | 31 | IEnumerator DecreateCoroutine2() 32 | { 33 | yield return new WaitForSeconds(10); 34 | List lstData = new List (); 35 | for (int i=0; i<50; ++i) { 36 | lstData.Add (i); 37 | } 38 | listView.SetData (lstData); 39 | } 40 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ##About 2 | This is a ListView solution for Unity’s new UI(uGUI) system. 3 | This solution provides following conveniences: 4 | 5 | - Attach scrollview related components automatically 6 | - Resize scrollview length as desired automatically 7 | - Reuse list items gameobject 8 | - Easy to use and easy to extend 9 | 10 | ##Usage 11 | 12 | 1. Create a list item prefab; 13 | 2. Create a Class derived from IUListItemView and implement its SetData function; 14 | 3. Attach the Class above to list item prefab; 15 | 4. Create an empty ui gameobject (with RectTransform attached) to show the listview; 16 | 5. Attach an IUListView implementation, eg. USimpleListView; 17 | 6. Set propertities of the IUListView subclass; 18 | 7. Create another MonoBehavior Class to invoke the IUListView's SetData function; 19 | 8. Run. 20 | 21 | ##Plan 22 | 23 | 1. USimpleListView: provides simple horizontal/vertical layout, one item per row/column (Completed); 24 | 2. UGridListView: provides grid horizontal/vertical layout, allowing multi items per row/column (Completed); 25 | 3. USimpleDiffSizeListView: provides simple horizontal/vertical layout, one item per row/column, each item has a different size (Completed). 26 | 27 | ##Author 28 | tnqiang 29 | 30 | ##License 31 | MIT 32 | -------------------------------------------------------------------------------- /Assets/Standard Assets/UListView/USimpleListView.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEngine.UI; 3 | using System.Collections; 4 | using System.Collections.Generic; 5 | using System; 6 | 7 | namespace NSUListView 8 | { 9 | public enum Alignment 10 | { 11 | Left, 12 | Mid, 13 | Right, 14 | Top, 15 | Bottom 16 | } 17 | 18 | public class USimpleListView : IUListView 19 | { 20 | [Tooltip("List Item Object, must set")] 21 | public GameObject itemPrefab; 22 | public Alignment alignment; 23 | private List lstItems; 24 | private Vector2 itemSize; 25 | 26 | public override void Init () 27 | { 28 | base.Init (); 29 | 30 | // record the item size 31 | IUListItemView itemView = itemPrefab.GetComponent (); 32 | itemSize = itemView.GetItemSize (null); 33 | 34 | // spawn pool for listitems 35 | lstItems = new List (); 36 | } 37 | 38 | public override int GetMaxShowItemNum() 39 | { 40 | int max = 0; 41 | // calculate the max show nums 42 | switch (layout) 43 | { 44 | case Layout.Horizontal: 45 | max = (int) Mathf.Ceil(scrollRectSize.x / (itemSize.x + spacing.x)) + 1; 46 | break; 47 | case Layout.Vertical: 48 | max = (int) Mathf.Ceil(scrollRectSize.y / (itemSize.y + spacing.y)) + 1; 49 | break; 50 | } 51 | return max; 52 | } 53 | 54 | public override int GetStartIndex() 55 | { 56 | Vector2 anchorPosition = content.anchoredPosition; 57 | // because the anchor is relative to the left-top corner of the scrollview 58 | // so the passed x is on the left, the passed y is on the top 59 | anchorPosition.x *= -1; 60 | int index = 0; 61 | 62 | switch (layout) 63 | { 64 | case Layout.Vertical: 65 | index = (int)(anchorPosition.y / (itemSize.y + spacing.y)); 66 | break; 67 | case Layout.Horizontal: 68 | index = (int)(anchorPosition.x / (itemSize.x + spacing.x)); 69 | break; 70 | } 71 | if (index < 0) index = 0; 72 | if (index >= lstData.Count) index = 0; 73 | return index; 74 | } 75 | 76 | public override Vector2 GetItemAnchorPos(int index) 77 | { 78 | Vector2 basePos = Vector2.zero; 79 | Vector2 offset = Vector2.zero; 80 | RectTransform contentRectTransform = content.transform as RectTransform; 81 | Vector2 contentRectSize = contentRectTransform.rect.size; 82 | 83 | if (layout == Layout.Horizontal) 84 | { 85 | basePos.x = -contentRectSize.x / 2 + itemSize.x / 2; 86 | offset.x = index * (itemSize.x + spacing.x); 87 | switch(alignment) 88 | { 89 | case Alignment.Top: 90 | offset.y = -(contentRectSize.y - itemSize.y)/2; 91 | break; 92 | case Alignment.Bottom: 93 | offset.y = (contentRectSize.y - itemSize.y)/2; 94 | break; 95 | } 96 | } 97 | else 98 | { 99 | basePos.y = contentRectSize.y / 2 - itemSize.y / 2; 100 | offset.y = -index * (itemSize.y + spacing.y); 101 | switch(alignment) 102 | { 103 | case Alignment.Left: 104 | offset.x = -(contentRectSize.x - itemSize.x)/2; 105 | break; 106 | case Alignment.Right: 107 | offset.x = (contentRectSize.x - itemSize.x)/2; 108 | break; 109 | } 110 | } 111 | 112 | return basePos + offset; 113 | } 114 | 115 | public override Vector2 GetContentSize() 116 | { 117 | Vector2 size = scrollRectSize; 118 | int count = lstData.Count; 119 | switch (layout) 120 | { 121 | case Layout.Horizontal: 122 | size.x = itemSize.x * count + spacing.x *( count > 0 ? count - 1 : count ); 123 | break; 124 | case Layout.Vertical: 125 | size.y = itemSize.y * count + spacing.y * ( count > 0 ? count - 1 : count ); 126 | break; 127 | } 128 | return size; 129 | } 130 | 131 | public override GameObject GetItemGameObject(int index) 132 | { 133 | if(index < lstItems.Count) 134 | { 135 | GameObject go = lstItems[index]; 136 | if(false == go.activeSelf) 137 | { 138 | go.SetActive(true); 139 | } 140 | return lstItems [index]; 141 | } 142 | else 143 | { 144 | GameObject go = GameObject.Instantiate(itemPrefab) as GameObject; 145 | lstItems.Add (go); 146 | return go; 147 | } 148 | } 149 | 150 | public override void HideNonuseableItems () 151 | { 152 | for (int i = GetCurrentShowItemNum(); lstItems != null && i < lstItems.Count; ++i) 153 | { 154 | if (lstItems[i].activeSelf) 155 | { 156 | lstItems[i].SetActive(false); 157 | } 158 | } 159 | } 160 | 161 | public override Vector2 GetItemSize(int index) 162 | { 163 | return itemSize; 164 | } 165 | } 166 | } -------------------------------------------------------------------------------- /Assets/Standard Assets/UListView/UGridListView.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEngine.UI; 3 | using System.Collections; 4 | using System.Collections.Generic; 5 | using System; 6 | 7 | namespace NSUListView 8 | { 9 | public class UGridListView : IUListView 10 | { 11 | [Tooltip("List Item Object, must set")] 12 | public GameObject itemPrefab; 13 | protected List lstItems; 14 | 15 | private int numPerRow; 16 | private int numPerColumn; 17 | private Vector2 padding; 18 | private Vector2 itemSize; 19 | 20 | public override void Init () 21 | { 22 | base.Init (); 23 | 24 | // record the item size 25 | IUListItemView itemView = itemPrefab.GetComponent (); 26 | itemSize = itemView.GetItemSize (null); 27 | 28 | // record max numbers per row/column 29 | numPerRow = (int)(scrollRectSize.x / (itemSize.x + spacing.x)); 30 | numPerColumn = (int)(scrollRectSize.y / (itemSize.y + spacing.y)); 31 | if (numPerRow < 1 || numPerColumn < 1) 32 | { 33 | Debug.LogError("ScrollRect size is too small to contain even one item"); 34 | } 35 | 36 | // to make items center aligned 37 | padding = Vector2.zero; 38 | 39 | // spawn pool for listitems 40 | lstItems = new List (); 41 | } 42 | 43 | public override int GetMaxShowItemNum() 44 | { 45 | int max = 0; 46 | // calculate the max show nums 47 | switch (layout) 48 | { 49 | case Layout.Horizontal: 50 | max = ((int)(scrollRectSize.x / itemSize.x) + 2) * numPerColumn; 51 | break; 52 | case Layout.Vertical: 53 | max = ((int)(scrollRectSize.y / itemSize.y) + 2) * numPerRow; 54 | break; 55 | } 56 | return max; 57 | } 58 | 59 | public override int GetStartIndex() 60 | { 61 | Vector2 anchorPosition = content.anchoredPosition; 62 | anchorPosition.x *= -1; 63 | int index = 0; 64 | 65 | switch (layout) 66 | { 67 | case Layout.Vertical: 68 | index = (int)(anchorPosition.y / (itemSize.y + spacing.y)) * numPerRow; 69 | break; 70 | case Layout.Horizontal: 71 | index = (int)(anchorPosition.x / (itemSize.x + spacing.x)) * numPerColumn; 72 | break; 73 | } 74 | if (index < 0) index = 0; 75 | if (index >= lstData.Count) index = 0; 76 | return index; 77 | } 78 | 79 | public override Vector2 GetItemAnchorPos(int index) 80 | { 81 | Vector2 basePos = Vector2.zero; 82 | Vector2 offset = Vector2.zero; 83 | RectTransform contentRectTransform = content.transform as RectTransform; 84 | Vector2 contentRectSize = contentRectTransform.rect.size; 85 | 86 | if (layout == Layout.Horizontal) 87 | { 88 | int offsetIndex = index % numPerColumn; 89 | basePos.x = -contentRectSize.x / 2 + itemSize.x / 2; 90 | offset.x = (index / numPerColumn) * (itemSize.x + spacing.x); 91 | offset.y = contentRectSize.y / 2 - itemSize.y / 2 - offsetIndex * (itemSize.y + spacing.y); 92 | } 93 | else 94 | { 95 | int offsetIndex = index % numPerRow; 96 | basePos.y = contentRectSize.y / 2 - itemSize.y / 2; 97 | offset.y = -(index / numPerRow) * (itemSize.y + spacing.y); 98 | offset.x = -(contentRectSize.x - itemSize.x)/2 + offsetIndex * (itemSize.x + spacing.x); 99 | } 100 | 101 | return basePos + offset + padding; 102 | } 103 | 104 | public override Vector2 GetContentSize() 105 | { 106 | Vector2 size = scrollRectSize; 107 | int count = lstData.Count; 108 | 109 | switch (layout) 110 | { 111 | case Layout.Horizontal: 112 | count = (count + numPerColumn - 1) / numPerColumn; 113 | size.x = itemSize.x * count + spacing.x *( count > 0 ? count -1 : count ); 114 | break; 115 | case Layout.Vertical: 116 | count = (count + numPerRow - 1) / numPerRow; 117 | size.y = itemSize.y * count + spacing.y * ( count > 0 ? count - 1 : count ); 118 | break; 119 | } 120 | return size; 121 | } 122 | 123 | public override GameObject GetItemGameObject(int index) 124 | { 125 | if(index < lstItems.Count) 126 | { 127 | GameObject go = lstItems[index]; 128 | if(false == go.activeSelf) 129 | { 130 | go.SetActive(true); 131 | } 132 | return lstItems [index]; 133 | } 134 | else 135 | { 136 | GameObject go = GameObject.Instantiate(itemPrefab) as GameObject; 137 | lstItems.Add (go); 138 | return go; 139 | } 140 | } 141 | 142 | public override void HideNonuseableItems () 143 | { 144 | for (int i = lstData.Count; lstItems != null && i < lstItems.Count; ++i) 145 | { 146 | if(lstItems[i].activeSelf) 147 | { 148 | lstItems[i].SetActive(false); 149 | } 150 | } 151 | } 152 | 153 | public override Vector2 GetItemSize(int index) 154 | { 155 | return itemSize; 156 | } 157 | } 158 | } -------------------------------------------------------------------------------- /Assets/Standard Assets/UListView/USimpleDiffSizeListView.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEngine.UI; 3 | using System.Collections; 4 | using System.Collections.Generic; 5 | using System; 6 | 7 | namespace NSUListView 8 | { 9 | public class USimpleDiffSizeListView : IUListView 10 | { 11 | [Tooltip("List Item Object, must set")] 12 | public GameObject itemPrefab; 13 | public Alignment alignment; 14 | private List lstItems; 15 | private IUListItemView itemView; 16 | 17 | public override void Init () 18 | { 19 | base.Init (); 20 | lstItems = new List (); 21 | itemView = itemPrefab.GetComponent(); 22 | } 23 | 24 | public override int GetMaxShowItemNum() 25 | { 26 | int max = 0; 27 | int index = GetStartIndex(); 28 | float sum = 0; 29 | switch (layout) 30 | { 31 | case Layout.Horizontal: 32 | while(index < lstData.Count && sum < scrollRectSize.x) 33 | { 34 | sum += (itemView.GetItemSize(lstData[index]).x + spacing.x); 35 | index++; 36 | max++; 37 | } 38 | break; 39 | case Layout.Vertical: 40 | while(index < lstData.Count && sum < scrollRectSize.x) 41 | { 42 | sum += (itemView.GetItemSize(lstData[index]).y + spacing.y); 43 | index++; 44 | max++; 45 | } 46 | break; 47 | } 48 | return max + 1; 49 | } 50 | 51 | public override int GetStartIndex() 52 | { 53 | Vector2 anchorPosition = content.anchoredPosition; 54 | anchorPosition.x *= -1; 55 | int index = -1; 56 | float sum = 0; 57 | 58 | switch (layout) 59 | { 60 | case Layout.Horizontal: 61 | sum = -spacing.x; 62 | for(int i=0; i= lstData.Count) index = 0; 96 | 97 | return index; 98 | } 99 | 100 | public override Vector2 GetItemAnchorPos(int index) 101 | { 102 | Vector2 basePos = Vector2.zero; 103 | Vector2 offset = Vector2.zero; 104 | RectTransform contentRectTransform = content.transform as RectTransform; 105 | Vector2 contentRectSize = contentRectTransform.rect.size; 106 | 107 | if (layout == Layout.Horizontal) 108 | { 109 | basePos.x = -contentRectSize.x / 2 - itemView.GetItemSize(lstData[index]).x / 2; 110 | for(int i=0; i <= index; ++i) 111 | { 112 | offset.x += (itemView.GetItemSize(lstData[i]).x + spacing.x); 113 | } 114 | 115 | switch(alignment) 116 | { 117 | case Alignment.Top: 118 | offset.y = -(contentRectSize.y - itemView.GetItemSize(lstData[index]).y)/2; 119 | break; 120 | case Alignment.Bottom: 121 | offset.y = (contentRectSize.y - itemView.GetItemSize(lstData[index]).y)/2; 122 | break; 123 | } 124 | } 125 | else 126 | { 127 | basePos.y = contentRectSize.y / 2 + itemView.GetItemSize(lstData[index]).y / 2; 128 | for(int i=0; i <= index; ++i) 129 | { 130 | offset.y -= (itemView.GetItemSize(lstData[i]).y + spacing.y); 131 | } 132 | switch(alignment) 133 | { 134 | case Alignment.Left: 135 | offset.x = -(contentRectSize.x - itemView.GetItemSize(lstData[index]).x)/2; 136 | break; 137 | case Alignment.Right: 138 | offset.x = (contentRectSize.x - itemView.GetItemSize(lstData[index]).x)/2; 139 | break; 140 | } 141 | } 142 | return basePos + offset; 143 | } 144 | 145 | public override Vector2 GetContentSize() 146 | { 147 | Vector2 size = scrollRectSize; 148 | switch (layout) 149 | { 150 | case Layout.Horizontal: 151 | size.x = 0; 152 | break; 153 | case Layout.Vertical: 154 | size.y = 0; 155 | break; 156 | } 157 | 158 | for (int i=0; i lstData; 27 | protected Vector2 leftTopCorner = Vector2.zero; 28 | private bool leftTopCornerInit = false; 29 | 30 | public virtual void Init() 31 | { 32 | // set attributes of scrollrect 33 | scrollRect = GetComponent (); 34 | scrollRect.onValueChanged.AddListener (OnValueChanged); 35 | 36 | // set the scroll direction 37 | switch (layout) 38 | { 39 | case Layout.Horizontal: 40 | scrollRect.horizontal = true; 41 | scrollRect.vertical = false; 42 | break; 43 | case Layout.Vertical: 44 | scrollRect.horizontal = false; 45 | scrollRect.vertical = true; 46 | break; 47 | } 48 | 49 | // add a scrollrect content 50 | GameObject go = new GameObject (); 51 | go.name = "content"; 52 | content = go.AddComponent (typeof(RectTransform)) as RectTransform; 53 | content.SetParent (transform); 54 | content.pivot = new Vector2 (0, 1); 55 | content.anchorMin = content.anchorMax = content.pivot; 56 | content.anchoredPosition = Vector2.zero; 57 | content.localScale = Vector3.one; 58 | scrollRect.content = content; 59 | 60 | // record some sizes 61 | RectTransform scrollRectTransform = scrollRect.transform as RectTransform; 62 | scrollRectSize = scrollRectTransform.rect.size; 63 | 64 | // add mask 65 | if (needMask) 66 | { 67 | Image image = gameObject.AddComponent(typeof(Image)) as Image; 68 | image.color = new Color32(0, 0, 0, 5); 69 | gameObject.AddComponent(typeof(Mask)); 70 | } 71 | } 72 | 73 | public void SetData(List lstData) 74 | { 75 | if (false == initialized) 76 | { 77 | Init(); 78 | initialized = true; 79 | } 80 | 81 | this.lstData = lstData; 82 | RefreshListView (); 83 | } 84 | 85 | private void OnValueChanged(Vector2 pos) 86 | { 87 | int startIndex = GetStartIndex (); 88 | if (startIndex != lastStartInex 89 | && startIndex >= 0) 90 | { 91 | RefreshListView(); 92 | lastStartInex = startIndex; 93 | } 94 | } 95 | 96 | protected void RefreshListView() 97 | { 98 | // set the content size 99 | Vector2 size = GetContentSize (); 100 | RectTransform contentRectTransform = content.transform as RectTransform; 101 | contentRectTransform.sizeDelta = size; 102 | 103 | // set the item postion and data 104 | int startIndex = GetStartIndex (); 105 | if (startIndex < 0) startIndex = 0; 106 | 107 | for (int i=0; i(); 116 | itemView.SetData(lstData[startIndex + i]); 117 | } 118 | 119 | // dont show the extra items shown before 120 | HideNonuseableItems (); 121 | 122 | // set the progress: 123 | int dataCount = GetDataCount(); 124 | dataCount -= (GetMaxShowItemNum ()-2); 125 | if (dataCount < 1) dataCount = 1; 126 | float progress = (startIndex + 1)/(float)dataCount; 127 | progress = Mathf.Clamp01(progress); 128 | OnProgress(progress); 129 | } 130 | 131 | /// 132 | /// Gets the current show item number. 133 | /// 134 | /// The current show item number. 135 | protected int GetCurrentShowItemNum() 136 | { 137 | int startIndex = GetStartIndex (); 138 | int maxShowNum = GetMaxShowItemNum (); 139 | int maxItemNum = lstData.Count - startIndex; 140 | return maxShowNum < maxItemNum ? maxShowNum : maxItemNum; 141 | } 142 | 143 | /// 144 | /// Gets the top left corner screen point. 145 | /// 146 | /// The top left corner screen point. 147 | private Vector2 GetTopLeftCornerScreenPoint() 148 | { 149 | if (false == leftTopCornerInit) 150 | { 151 | RectTransform rectTrans = scrollRect.transform as RectTransform; 152 | Vector3[] corners = new Vector3[4]; 153 | rectTrans.GetWorldCorners (corners); 154 | Canvas canvas = GetComponentInParent (); 155 | if (null != canvas && null != canvas.worldCamera && RenderMode.ScreenSpaceOverlay != canvas.renderMode) { 156 | Camera cam = canvas.worldCamera; 157 | corners [1] = cam.WorldToScreenPoint (corners [1]); 158 | } 159 | leftTopCorner = new Vector2 (corners [1].x, corners [1].y); 160 | } 161 | return leftTopCorner; 162 | } 163 | 164 | /// 165 | /// Raises the pointer enter event. 166 | /// 167 | /// Event data. 168 | public void OnPointerClick(PointerEventData eventData) 169 | { 170 | //get the pos relative to left-top corner of the scrollview 171 | Vector2 clickPos = eventData.position - GetTopLeftCornerScreenPoint(); 172 | Vector2 anchorPosition = -content.anchoredPosition; 173 | 174 | anchorPosition += clickPos; 175 | anchorPosition.x -= content.rect.size.x / 2; 176 | anchorPosition.y += content.rect.size.y / 2; 177 | 178 | // set the item postion and data 179 | int startIndex = GetStartIndex (); 180 | if (startIndex < 0) startIndex = 0; 181 | 182 | for (int i=0; i 196 | /// Raises the click event. 197 | /// 198 | /// Position. 199 | public virtual void OnClick(int index) 200 | { 201 | } 202 | 203 | /// 204 | /// Raises the progress event when progress change 205 | /// 206 | /// Progress. 207 | public virtual void OnProgress(float progress) 208 | { 209 | } 210 | 211 | /// 212 | /// Gets the data count. 213 | /// default return 1 214 | /// 215 | /// The data count. 216 | public virtual int GetDataCount() 217 | { 218 | if (null == lstData)return 1; 219 | else return lstData.Count; 220 | } 221 | 222 | /// 223 | /// Gets the max show item number. 224 | /// 225 | /// The max show item number. 226 | public abstract int GetMaxShowItemNum(); 227 | /// 228 | /// Gets the rect tranform size of the content of the ScrollRect 229 | /// 230 | /// The content size. 231 | public abstract Vector2 GetContentSize(); 232 | /// 233 | /// Gets the anchor position of the item indexed index 234 | /// Assume that anchorMin = anchorMax = pivot = new Vector(0.5f, 0.5f) 235 | /// 236 | /// The item anchor position. 237 | /// index of item 238 | public abstract Vector2 GetItemAnchorPos(int index); 239 | /// 240 | /// Gets the start index of the item to be shown 241 | /// 242 | /// The start index(start from 0) 243 | public abstract int GetStartIndex(); 244 | /// 245 | /// Gets the item game object. 246 | /// 247 | /// The item game object. 248 | /// Index. 249 | public abstract GameObject GetItemGameObject(int index); 250 | /// 251 | /// Hides the nonuseable items. 252 | /// 253 | public abstract void HideNonuseableItems(); 254 | /// 255 | /// Gets the size of the item of specified index 256 | /// 257 | /// The item size. 258 | /// Index. 259 | public abstract Vector2 GetItemSize(int index); 260 | } 261 | } --------------------------------------------------------------------------------