Unity自带的滚动列表如果创建过多,如同时创建上千,上万,易引起卡顿,为解决这种现象的发生,这里实现虚拟列表来处理这种情况。原理就是初始化固定个数的item数,当滚动列表向下滚动至可视范围外的时候将第一个Item移动至最底层,如此循环执行,向上滚动如是,于是我们只用关注数据的变化,动态改变item的数据即可。
站在巨人的肩膀上才能看的更远(拿来主义与总结)
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class VirtualListFacade : MonoBehaviour
{
public VirtualList uiList;
// Use this for initialization
void Start()
{
uiList.onSelectedEvent = OnSelectedEventHandler;
List<int> listData = new List<int>();
for (int i = 0; i < 1000; i++)
{
listData.Add(i);
}
uiList.Data(listData);
}
private void OnSelectedEventHandler(ListItem item)
{
Debug.LogError("选择的单元数据为:" + item.GetData().ToString());
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
List<int> listData = new List<int>();
int count = Random.Range(100, 1000);
for (int i = 0; i < count; i++)
{
listData.Add(i);
}
uiList.Data(listData);
}
}
}
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;
public class VirtualList : MonoBehaviour
{
/// <summary>
/// 滚动的方向
/// </summary>
enum Direction
{
Horizontal,//水平方向
Vertical//垂直方向
}
/// <summary>
/// 离上边的距离
/// </summary>
[SerializeField]
private float topPadding = 0;
/// <summary>
/// 离下边的距离
/// </summary>
[SerializeField]
private float bottomPadding = 0;
[SerializeField]
private RectTransform m_Cell;
[SerializeField]
private Vector2 m_Page = new Vector2(1, 1);//必须设置;几行几列
[SerializeField]
Direction direction = Direction.Horizontal;
[SerializeField, Range(4, 10)]
private int m_BufferNo; //缓存的Item数(在手动设置的基础上增加缓存格子数)
/// <summary>
/// 间隔
/// </summary>
[SerializeField]
private float cellGapX = 0f;
[SerializeField]
private float cellGapY = 0f;
public delegate void OnSelectedEvent(ListItem item);
/// <summary>
/// 选择事件 但组件上一定要有Button组件 设置要在Data()设置数据前
/// </summary>
public OnSelectedEvent onSelectedEvent;//
private List<RectTransform> m_InstantiateItems = new List<RectTransform>();
private List<RectTransform> m_oldItems = new List<RectTransform>();
private IList m_Datas;
public Vector2 CellRect
{
get
{
return m_Cell != null ? new Vector2(cellGapX + m_Cell.sizeDelta.x, cellGapY + m_Cell.sizeDelta.y) : new Vector2(100, 100);
}
}
public float CellScale { get { return direction == Direction.Horizontal ? CellRect.x : CellRect.y; } }
private float m_PrevPos = 0;
//当