prefabricated structure
The script is mounted on Rect
using System; using System.Collections.Generic; using UnityEngine; using UnityEngine. EventSystems; using UnityEngine.UI; /// <summary> /// Script to mount manually /// </summary> public class ScrollListLoop: MonoBehaviour { private int padH; private int recordOperateIndex; private int dataLength; private int operateIndex = 0; private int showLenth; private Transform grid; private Transform item; private RectTransform rectTransformGrid; private RectTransform rectTransformItem; private ScrollRect rectSroll; private Action<Transform, int> callBack; private List<Transform> itemListPool; private List<ItemIndex> nowShowData=new List<ItemIndex>(); private List<ItemIndex> freeItem = new List<ItemIndex>(); private List<int> needShowIndex = new List<int>(); /// <summary> /// External call /// </summary> /// <param name="callBackTemp">Entry refresh callback</param> /// <param name="gridTemp">entry root directory</param> /// <param name="itemTemp">entry</param> /// <param name="showLength">Number of initialization entries</param> /// <param name="dataLength">data length</param> /// <param name="padHTemp">entry spacing</param> public void Init(Action<Transform,int> callBackTemp,Transform gridTemp, Transform itemTemp,int showLength ,int dataLength,int padHTemp=10) { grid = gridTemp; item = itemTemp; padH = padHTemp; callBack = callBackTemp; rectSroll = gameObject. GetComponent<ScrollRect>(); rectSroll.onValueChanged.AddListener(ScrollRectIng); rectTransformGrid = grid. GetComponent<RectTransform>(); rectTransformItem = item. GetComponent<RectTransform>(); rectTransformGrid.sizeDelta = new Vector2(rectTransformGrid.sizeDelta.x, rectTransformItem.sizeDelta.y * dataLength + padH * (dataLength - 1)); this. showLenth = showLength; this.dataLength = dataLength; for (int i = 0; i < showLength; i ++ ) { Transform needItem = GetItem(); nowShowData. Add(needItem. GetComponent<ItemIndex>()); SetInfo(needItem, i); } } /// <summary> /// Swipe to display changes and refresh /// </summary> private void UpdateShowData() { needShowIndex. Clear(); freeItem. Clear(); for (int i = operateIndex; i < showLenth + operateIndex; i ++ ) { if (!IsExist(i)) { needShowIndex. Add(i); } } for (int i = 0; i < nowShowData. Count; i ++ ) { if (!IsExistItemIndex(nowShowData[i].Index)) { freeItem.Add(nowShowData[i]); } } if (needShowIndex.Count != 0 & amp; & amp; freeItem.Count != 0) { for (int i = 0; i < needShowIndex. Count; i ++ ) { ItemIndex itemIndex = freeItem[0]; freeItem. RemoveAt(0); SetInfo(itemIndex. transform, needShowIndex[i]); } } } private bool IsExist(int index) { for (int i = 0; i < nowShowData. Count; i ++ ) { if (nowShowData[i].Index == index) return true; } return false; } private bool IsExistItemIndex(int index) { for (int i = operateIndex; i < showLenth + operateIndex; i ++ ) { if (i == index) return true; } return false; } private void ScrollRectIng(Vector2 pos) { Vector2 gridPos = rectTransformGrid. anchoredPosition; float itemH = item.GetComponent<RectTransform>().sizeDelta.y; operateIndex =(int)Mathf.Floor(gridPos.y/(itemH + padH)); operateIndex = operateIndex < 0 ? 0 : operateIndex; operateIndex = operateIndex > dataLength - showLenth ? dataLength - showLenth : operateIndex; if (recordOperateIndex != operateIndex) { UpdateShowData(); recordOperateIndex = operateIndex; } } /// <summary> /// set data /// </summary> /// <param name="useItem"></param> /// <param name="index"></param> private void SetInfo(Transform useItem, int index) { RectTransform rectTransform = useItem. GetComponent<RectTransform>(); float height = rectTransform.sizeDelta.y; float h = 0; if (index > 0) { h = index * (hight + padH); } rectTransform.anchoredPosition = new Vector2(0,-h); ItemIndex itemIndex = useItem. GetComponent<ItemIndex>(); itemIndex. SetIndex(index); callBack(useItem, index); } /// <summary> /// Get item prefab /// </summary> /// <returns></returns> private Transform GetItem() { if (itemListPool == null) { itemListPool = new List<Transform>(); } Transform useItem = itemListPool.Count==0?null:itemListPool[0]; if (useItem==null) { Transform t=Instantiate(item); ItemIndex itemIndex = t.GetComponent<ItemIndex>();///index custom mounted on the item if (itemIndex == null) { t.gameObject.AddComponent<ItemIndex>(); } itemListPool. Add(t); t. SetParent(grid); } useItem = itemListPool[0]; itemListPool. RemoveAt(0); useItem.gameObject.SetActive(true); return useItem; } }
ItemIndex class
using System. Collections; using System.Collections.Generic; using UnityEngine; public class ItemIndex : MonoBehaviour { private int index; public int Index { get { return index; } } public void SetIndex(int index) { this. index = index; } }
entry code
using System. Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class MainList : MonoBehaviour { private ScrollListLoop scrollListLoop; public Transform grid; public Transform item; List<int> list; // Start is called before the first frame update void Start() { list = new List<int>(); for (int i = 1; i <= 20; i ++ ) { list.Add(i); } scrollListLoop = transform. gameObject. AddComponent<ScrollListLoop>(); scrollListLoop.Init(SetInfo, grid, item , 10, list.Count); } void SetInfo(Transform item, int index) { Text text = item. Find("Text"). GetComponent<Text>(); text.text = list[index].ToString(); } }