UGUI ScrollView无限滚动的简单实现
无限滚动组件是项目工程里常用的优化方案,在网上找了许多参考方案,但是看着都比较复杂,一些功能比较多的插件源码行数甚至在两千以上,暂时没有时间去研究。
这里提供一个最基础的无限滚动源码,旨在为UGUI初学者提供参考,若需更多功能需自行添加或者使用更成熟的插件。若有不成熟的地方,请大家指教。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class SuperScrollView : MonoBehaviour {
private ScrollRect mScrollRect;
private RectTransform mContentRect;
public GameObject itemPrefab;
public float itemHeight;//item的高度(全都一样)
public int maxItemCount; //最大item生成数量,真实item生成数量的阀值
public int datasNum;//数据数量
private int currentItemCount;//已生成的item的数量
//记录最上和最下的item索引
private int firstIndex;
private int lastIndex;
private List<GameObject> itemList;
// Use this for initialization
void Start () {
itemList = new List<GameObject>();
mScrollRect = transform.GetComponent<ScrollRect>();
mContentRect = mScrollRect.content.transform.GetComponent<RectTransform>();
mScrollRect.onValueChanged.AddListener((Vector2 vec) => OnScrollMove(vec));
SetScroller();
}
public void SetScroller()
{
SetContentHeight();
InitCountent();
}
//设置滚动条的Content高度
public void SetContentHeight()
{
mContentRect.sizeDelta = new Vector2(mContentRect.sizeDelta.x, itemHeight * datasNum);
}
//初始化生成固定数量的Item
public void InitCountent()
{
int needItem = Mathf.Clamp(datasNum, 0, maxItemCount+1);
for (int i = 0; i < needItem; i++)
{
GameObject _obj = Instantiate(itemPrefab);
_obj.transform.SetParent(mContentRect.transform);
_obj.name = i.ToString();
_obj.transform.Find("Text").GetComponent<Text>().text = i.ToString();
RectTransform _rectTrans = _obj.GetComponent<RectTransform>();
_rectTrans.pivot = new Vector2(0.5f, 1);
_rectTrans.anchorMax = new Vector2(0.5f, 1);
_rectTrans.anchorMin = new Vector2(0.5f, 1);
_rectTrans.anchoredPosition = new Vector2(0, -itemHeight * currentItemCount);
currentItemCount += 1;
lastIndex = i;
itemList.Add(_obj);
}
}
private void OnScrollMove(Vector2 pVec)
{
//向下滚动
while (mContentRect.anchoredPosition.y > (firstIndex + 1) * itemHeight && lastIndex != datasNum - 1)
{
//思路是List中的保存的GameObject顺序与真实显示的物体保持一致
GameObject _first = itemList[0];
RectTransform _rectTrans = _first.GetComponent<RectTransform>();
//将首个物体移出List,再添加到List最后端
itemList.RemoveAt(0);
itemList.Add(_first);
//将这个物体移到最下方
_rectTrans.anchoredPosition = new Vector2(0, -(lastIndex+1) * itemHeight);
firstIndex += 1;
lastIndex += 1;
//修改显示
_first.name = lastIndex.ToString();
_first.transform.Find("Text").GetComponent<Text>().text = _first.name;
}
//向上滚动
while (mContentRect.anchoredPosition.y < firstIndex * itemHeight && firstIndex != 0)
{
GameObject _last = itemList[itemList.Count - 1];
RectTransform _rectTrans = _last.GetComponent<RectTransform>();
itemList.RemoveAt(itemList.Count - 1);
itemList.Insert(0, _last);
_rectTrans.anchoredPosition = new Vector2(0, -(firstIndex - 1) * itemHeight);
firstIndex -= 1;
lastIndex -= 1;
_last.name = firstIndex.ToString();
_last.transform.Find("Text").GetComponent<Text>().text = _last.name;
}
}
}
代码挂在有ScrollRect组件的物体上:
效果: