Unity 支持水平,竖直。无限轮播 ,基于UGUI的ScrollView组件
1,实图  2,代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class BaseList<T>
{
public delegate Transform SetElement(Transform transform, T itemData);
public int 列数 = 1;
public float 行间距;
public float 列间距;
private int 行数 = 1;
private Transform content;
private float parentWidth = 0;
private float parentHeight = 0;
private Transform itemTransform;
private float itemWidth = 0;
private float itemHeight = 0;
private int 显示数量 = 0;
private float 可视范围 = 0;
private float 内容总长度 = 0;
private bool is水平滑动;
private float contentStartPos = 0;
private Transform rootTransform = null;
private List<T> dataList;
private SetElement setElement;
private Stack<Transform> itemStack;
private Dictionary<int, Transform> itemDictionary = new Dictionary<int, Transform>();
public void SetParam(List<T> list, SetElement setElement, Transform root, float rowDistance, float columnDistance, bool isH)
{
is水平滑动 = isH;
行间距 = rowDistance;
列间距 = columnDistance;
rootTransform = root;
dataList = list;
this.setElement = setElement;
InitParameter();
}
private void InitParameter()
{
content = rootTransform.Find("Viewport/Content");
itemTransform = rootTransform.Find("Viewport/Item").transform;
itemTransform.gameObject.SetActive(false);
Rect itemRect = itemTransform.GetComponent<RectTransform>().rect;
itemWidth = itemRect.width;
itemHeight = itemRect.height;
parentWidth = rootTransform.GetComponent<RectTransform>().rect.width;
parentHeight = rootTransform.GetComponent<RectTransform>().rect.height;
if (!is水平滑动)
{
contentStartPos = content.localPosition.y;
可视范围 = rootTransform.GetComponent<RectTransform>().rect.height;
行数 = (int)((parentHeight - (行间距 + itemHeight / 2)) / (行间距 + itemHeight) + 1);
}
else
{
contentStartPos = content.localPosition.x;
可视范围 = rootTransform.GetComponent<RectTransform>().rect.width;
列数 = (int)((parentWidth - (列间距 + itemWidth / 2)) / (列间距 + itemWidth) + 1);
}
显示数量 = 列数 * 行数;
Debug.Log("列数:" + 列数 + "行数:" + 行数 + "显示数量:" + 显示数量);
SetData();
}
public void SetData()
{
int maxCount = dataList.Count;
int index = 0;
if (!is水平滑动)
{
内容总长度 = (itemHeight + 行间距) * maxCount / 列数;
content.GetComponent<RectTransform>().sizeDelta = new Vector2(content.GetComponent<RectTransform>().sizeDelta.x, 内容总长度 + 10);
}
else
{
内容总长度 = (itemWidth + 列间距) * maxCount / 行数;
content.GetComponent<RectTransform>().sizeDelta = new Vector2(内容总长度 + 10, content.GetComponent<RectTransform>().sizeDelta.y);
}
Debug.Log("内容总长度:" + 内容总长度);
ScrollRect scrollRect = rootTransform.GetComponent<ScrollRect>();
if (scrollRect != null)
{
scrollRect.onValueChanged.RemoveAllListeners();
scrollRect.onValueChanged.AddListener(OnValueChange);
}
if (!is水平滑动)
{
for (int row = 0; row < 行数 + 1; row++)
{
for (int column = 0; column < 列数; column++)
{
if (index >= maxCount)
return;
Transform itemTrans = setElement(GameObject.Instantiate(itemTransform.gameObject, content.transform).transform, dataList[index]);
itemTrans.gameObject.SetActive(true);
float y = -(row * (itemHeight + 行间距) + itemHeight / 2 + 行间距);
itemTrans.GetComponent<RectTransform>().anchoredPosition = new Vector2(0, y);
itemDictionary.Add(index, itemTrans);
index++;
}
if (index >= maxCount)
return;
}
}
else
{
for (int col = 0; col < 列数 + 1; col++)
{
for (int row = 0; row < 行数; row++)
{
if (index >= maxCount)
return;
Transform itemTrans = setElement(GameObject.Instantiate(itemTransform.gameObject, content.transform).transform, dataList[index]);
itemTrans.gameObject.SetActive(true);
float x = (col * (itemWidth + 列间距) + itemWidth / 2 + 列间距);
itemTrans.GetComponent<RectTransform>().anchoredPosition = new Vector2(x, 0);
itemDictionary.Add(index, itemTrans);
index++;
}
if (index >= maxCount)
return;
}
}
}
public void OnValueChange(Vector2 vector)
{
int showIndex = GetShowIndex();
if (showIndex < 1) showIndex = 1;
List<int> uplist = new List<int>();
List<int> downList = new List<int>();
foreach (int key in itemDictionary.Keys)
{
if (!is水平滑动)
{
if (key < showIndex - 1 && key + ((列数 * (行数 + 1))) < dataList.Count)
uplist.Add(key);
if (key > showIndex + (列数 * (行数 + 1)) - 列数 - 1)
downList.Add(key);
}
else
{
if (key < showIndex - 1 && key + (行数 * (列数 + 1)) < dataList.Count)
uplist.Add(key);
if (key > showIndex + (行数 * (列数 + 1)) - 行数 - 1)
downList.Add(key);
}
}
foreach (int cursor in uplist)
{
Transform trans;
if (itemDictionary.TryGetValue(cursor, out trans))
{
itemDictionary.Remove(cursor);
if (!is水平滑动)
{
int row = cursor / 列数 + (列数 * (行数 + 1)) / 列数;
int indexPos = cursor + (列数 * (行数 + 1));
float colum = -(row * (itemHeight + 行间距) + itemHeight / 2 + 行间距);
if ((列数 * (行数 + 1)) + cursor < dataList.Count)
{
trans = setElement(trans, dataList[(列数 * (行数 + 1)) + cursor]);
trans.GetComponent<RectTransform>().anchoredPosition = new Vector2(0, colum);
itemDictionary.Add(indexPos, trans);
}
}
else
{
int col = cursor / 行数 + (行数 * (列数 + 1)) / 行数;
int indexPos = cursor + (行数 * (列数 + 1));
float colum = (col * (itemWidth + 列间距) + itemWidth / 2 + 列间距);
if ((行数 * (列数 + 1)) + cursor < dataList.Count)
{
trans = setElement(trans, dataList[(行数 * (列数 + 1)) + cursor]);
trans.GetComponent<RectTransform>().anchoredPosition = new Vector2(colum, 0);
itemDictionary.Add(indexPos, trans);
}
}
}
}
foreach (int cursor in downList)
{
Transform trans;
if (itemDictionary.TryGetValue(cursor, out trans))
{
itemDictionary.Remove(cursor);
if (!is水平滑动)
{
int row = cursor / 列数 - (列数 * (行数 + 1)) / 列数;
int indexPos = cursor - (列数 * (行数 + 1));
float rowPos = -(row * (itemHeight + 行间距) + itemHeight / 2 + 行间距);
trans = setElement(trans, dataList[cursor - (列数 * (行数 + 1))]);
trans.GetComponent<RectTransform>().anchoredPosition = new Vector2(0, rowPos);
itemDictionary.Add(indexPos, trans);
}
else
{
int col = cursor / 行数 - (行数 * (列数 + 1)) / 行数;
int indexPos = cursor - (行数 * (列数 + 1));
float colPos = (col * (itemWidth + 列间距) + itemWidth / 2 + 列间距);
trans = setElement(trans, dataList[cursor - (行数 * (列数 + 1))]);
trans.GetComponent<RectTransform>().anchoredPosition = new Vector2(colPos, 0);
itemDictionary.Add(indexPos, trans);
}
}
}
}
public int GetShowIndex()
{
float startPos = contentStartPos;
float currentPos;
int line = 0;
int startIndex = -1;
if (!is水平滑动)
{
currentPos = content.localPosition.y;
line = ((int)((currentPos - startPos) / (itemHeight + 行间距)) + 1);
startIndex = line * 列数 - 列数 + 1;
}
else
{
currentPos = content.localPosition.x;
line = ((int)(Mathf.Abs(currentPos - startPos) / (itemWidth + 列间距)) + 1);
startIndex = line * 行数 - 行数 + 1;
}
return startIndex;
}
}
3,使用时调用
BaseList<T> baseList = new BaseList<T>();
baseList.SetParam(list, setElement, this.transform, rowDistance, columnDistance, is水平滑动);
4,下方是使用例子欢迎下载 示例下载地址
|