1.根据InfiniteElem 的高度和总个数,计算出Content的长度,
2.根据Content所在的滚动位置,计算出当前哪些InfiniteElem显示在列表中
3.循环是生成的几个InfiniteElem显示列表内容,实现无限列表
CSDN下载:https://download.csdn.net/download/qq_33205561/87672224
循环列表组件
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class InfiniteList : MonoBehaviour
{
public ScrollRect scrollRect;
public float top;
public float bottom;
public float interval;
public InfiniteElem elem;
public int elemCount;
float elemHeight => elem.rectTransform.sizeDelta.y;
RectTransform content => scrollRect.content;
List<InfiniteData> datas = new List<InfiniteData>();
List<InfiniteElem> elems = new List<InfiniteElem>();
bool isInit = false;
private void Awake()
{
Init();
}
public void Init()
{
if (isInit) return;
isInit = true;
for (int i = 0; i < elemCount; i++)
{
GameObject go = GameObject.Instantiate(elem.gameObject, content);
InfiniteElem comp = go.GetComponent<InfiniteElem>();
elems.Add(comp);
comp.InitUI();
}
RefreshContent();
scrollRect.onValueChanged.AddListener((v2) => {
RefreshElem(); });
}
public void SetDatas(List<InfiniteData> lst)
{
datas = lst;
RefreshContent();
}
public void AddData(InfiniteData data)
{
datas.Add(data);
RefreshContent();
}
public void RemoveData(InfiniteData data)
{
datas.Remove(data);
RefreshContent();
}
public void Clear()
{
datas.Clear();
RefreshContent();
}
public void Jump2Index(int index)
{
float y = Index2Y(index - 1);
Vector2 pos = content.anchoredPosition;
pos.y = y;
content.anchoredPosition = pos;
//刷新元素
RefreshElem();
}
public void Jump2Last()
{
scrollRect.verticalNormalizedPosition = 0;
//刷新元素
RefreshElem();
}
public void Jump2Begin()
{
Vector2 pos = content.anchoredPosition;
pos.y = 0;
content.anchoredPosition = pos;
//刷新元素
RefreshElem();
}
void RefreshContent()
{
//处理容器总长度
float height = 0;
height += elemHeight * datas.Count;
height += interval * (datas.Count - 1);
height += top + bottom;
Vector2 size = content.sizeDelta;
size.y = height;
content.sizeDelta = size;
//刷新元素
RefreshElem();
}
void RefreshElem()
{
int start = Y2Index(content.anchoredPosition.y);
int end = start + elemCount;
end = Mathf.Clamp(end, 0, datas.Count);
for (int i = 0; i < elems.Count; i++)
{
InfiniteElem elem = elems[i];
int index = start + i;
index = Mathf.Clamp(index, 0, datas.Count);
if (index >= end || index < 0)
{
elem.SetActive(false);
}
else
{
elem.SetActive(true);
elem.SetData(datas[index]);
float y = Index2Y(index);
elem.SetAnchoredPosY(-y);
}
}
}
float Index2Y(int index)
{
float y = 0;
y += top;
y += (elemHeight + interval) * (index);
return y;
}
int Y2Index(float y)
{
y -= top;
float h = interval + elemHeight;
int index = Mathf.FloorToInt(y / h);
return index;
}
}
列表元素基类:
列表上显示的Object继承于这个,
InitUI()会在初始化的时候调用
SetData()会在更新数据的时候调用
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data.Common;
using UnityEngine;
public class InfiniteElem : MonoBehaviour
{
InfiniteData data;
public void InitUI()
{
}
public RectTransform rectTransform
{
get
{
if (_rectTransform == null)
_rectTransform = GetComponent<RectTransform>();
return _rectTransform;
}
}
RectTransform _rectTransform;
virtual public void SetData(InfiniteData data)
{
this.data = data;
}
virtual public void SetAnchoredPosY(float y)
{
Vector3 pos = rectTransform.anchoredPosition;
pos.y = y;
rectTransform.anchoredPosition = pos;
}
virtual public void SetActive(bool boolean)
{
gameObject.SetActive(boolean);
}
}
数据基类
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class InfiniteData
{
}