优化滑动列表
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class ScrollList : MonoBehaviour
{
[SerializeField] ScrollRect scrollRect;
[SerializeField] RectTransform elemParent;
[SerializeField] RectTransform elem;
[SerializeField] RectTransform viewPort;
int count = 1000;
int defaultCreateCount = 6;
float visiableAreaHeight;
float visiableAreaWidth;
Vector2 elemSize;
Dictionary<int, ListElement> elemDic = new Dictionary<int, ListElement>();
List<ListElement> notUsedElemList = new List<ListElement>() { Capacity = 1000 };
private void Start()
{
visiableAreaHeight = viewPort.sizeDelta.y;
visiableAreaWidth = viewPort.sizeDelta.x;
elemSize = elem.sizeDelta;
var totalRow = Mathf.CeilToInt(count / 2.0f);
var totalHeight = elemSize.y * totalRow;
elemParent.sizeDelta = new Vector2(visiableAreaWidth, totalHeight);
for (int i = 0; i < defaultCreateCount; i++)
{
RectTransform obj = Instantiate(elem, elemParent);
var listElem = obj.GetComponent<ListElement>();
listElem.ShowContent(i.ToString());
obj.anchoredPosition = SetElemPos(i);
elemDic.Add(i, listElem);
}
scrollRect.onValueChanged.AddListener(ChangeValue);
}
Vector2 SetElemPos(int index)
{
int x = index / 2;
int y = index % 2;
return new Vector2(y * elemSize.y, -x * elemSize.x);
}
void ChangeValue(Vector2 value)
{
var visiableAreaTop = elemParent.anchoredPosition.y;
var visiableAreaBottom = visiableAreaTop + visiableAreaHeight;
int beginIndex = (int)(visiableAreaTop / elemSize.y) * 2;
int endIndex = (int)(visiableAreaBottom / elemSize.y) * 2 + 1;
for (int i = 0; i < beginIndex; i++)
{
if (elemDic.ContainsKey(i))
{
var listElem = elemDic[i];
elemDic.Remove(i);
notUsedElemList.Add(listElem);
}
}
for (int i = endIndex + 1; i < count; i++)
{
if (elemDic.ContainsKey(i))
{
var listElem = elemDic[i];
elemDic.Remove(i);
notUsedElemList.Add(listElem);
}
}
for (int i = beginIndex; i <= endIndex; i++)
{
if (i < count && i >= 0)
{
if (elemDic.ContainsKey(i))
{
var listElem = elemDic[i];
listElem.ShowContent(i.ToString());
}
else
{
if (notUsedElemList.Count > 0)
{
var temp = notUsedElemList[0];
(temp.transform as RectTransform).anchoredPosition = SetElemPos(i);
temp.ShowContent(i.ToString());
elemDic.Add(i, temp);
notUsedElemList.RemoveAt(0);
}
else
{
RectTransform obj = Instantiate(elem, elemParent);
obj.anchoredPosition = SetElemPos(i);
var listElem = obj.GetComponent<ListElement>();
listElem.ShowContent(i.ToString());
elemDic.Add(i, listElem);
}
}
}
}
}
}
元素
using UnityEngine;
using UnityEngine.UI;
public class ListElement : MonoBehaviour
{
[SerializeField] Text content;
public void ShowContent(string info)
{
content.text = info;
}
}