更新日期:2020年10月16日。
Github源码:[点我获取源码]
索引
- InfiniteList
- 使用
- 创建InfiniteListScrollRect
- InfiniteListScrollRect参数详解
- 重写数据类
- 重写元素类
- 编辑元素模板
- 添加数据
- 移除数据
- 清空数据
InfiniteList
InfiniteList为基于UGUI的ScrollRect无限滚动列表的一种实现,很多时候当我们的ScrollRect的视图中包含的数据无限多时,而同时可见的数据往往只有几条,大量不可见数据被Mask组件排除在肉眼可见范围之外,但他们依然存在,内存与DrawCall的消耗仍旧同时进行着,这是相当不明智的,所以,消灭这一部分隐藏数据的真身就是InfiniteList做的主要工作。
使用
创建InfiniteListScrollRect
在Hierarchy视图点击右键,选择菜单UI
-> ScrollView - InfiniteList
,在场景中创建一个无限滚动视野的默认对象:
InfiniteListScrollRect参数详解
1.Element Template
为无限列表元素的模板,你需要根据你的情况修改此模板。
2.Listing Direction
列表的排列方向,支持水平、垂直方向,但不支持同时水平+垂直布局。
3.Height
垂直布局时,单个元素高度,水平布局时,单个元素宽度。
4.Interval
列表布局时,元素之间的间隔距离。
5.其余参数为继承至ScrollRect的参数。
重写数据类
首先,你需要新建一个数据类型,继承至InfiniteListData
无限列表数据基类,比如下方的InfiniteListTestData:
/// <summary>
/// 无限列表测试数据
/// </summary>
public class InfiniteListTestData : InfiniteListData
{
public string Name;
}
需注意,一个数据对象对应一个无限列表中显示的元素,数据 <=> 元素,为一对一的关系。
重写元素类
然后,你需要新建一个元素类型,继承至InfiniteListElement
无限列表元素基类,比如下方的InfiniteListTestElement:
/// <summary>
/// 无限列表测试元素
/// </summary>
public class InfiniteListTestElement : InfiniteListElement
{
public Text Name;
public Button RemoveButton;
//元素属于的无限列表对象
private InfiniteListScrollRect _scrollRect;
//元素持有的数据
private InfiniteListTestData _data;
public override void UpdateData(InfiniteListScrollRect scrollRect, InfiniteListData data)
{
base.UpdateData(scrollRect, data);
_scrollRect = scrollRect;
_data = data as InfiniteListTestData;
Name.text = _data.Name;
RemoveButton.onClick.AddListener(() => { _scrollRect.RemoveData(_data); });
}
public override void ClearData()
{
base.ClearData();
_scrollRect = null;
_data = null;
RemoveButton.onClick.RemoveAllListeners();
}
}
需注意,UpdateData
方法为此元素在无限列表中可见时被调用,参数1为无限列表对象,参数2为此元素对应的数据。
ClearData
方法为此元素在无限列表中隐藏时被调用。
编辑元素模板
然后,需要用我们自己的元素类,替换掉元素模板ElementTemplate
上的元素类:
我们继续编辑元素模板,在其中添加一个Text用于显示文本,添加一个按钮用于点击后移除此元素(也即是从列表中移除此元素对应的数据),元素的高度我们设定为20
,在垂直排列时,无限列表只认高度
、和元素y
坐标值,x
坐标值会始终被设置为0,水平排列同理。
同时,我们要将我们设定的高度20
设置到InfiniteListScrollRect的面板,元素间的间隔我们设置为5
:
添加数据
目前无限列表只支持动态添加数据:
//无限列表对象
public InfiniteListScrollRect InfiniteList;
private string[] _surnames = new string[] { "张", "李", "王", "赵", "刘", "胡", "霍", "江", "唐", "欧阳", "司徒", "慕容", "轩辕", "皇甫", "西门" };
private string[] _names = new string[] { "三", "四", "五", "明", "强", "磊", "龙", "虎", "玉清", "博", "成", "航", "逸", "建国", "建军", "建党" };
private void Start()
{
List<InfiniteListTestData> datas = new List<InfiniteListTestData>();
for (int i = 0; i < 1000; i++)
{
InfiniteListTestData data = new InfiniteListTestData();
data.Name = (i + 1) + "." + RandomName();
datas.Add(data);
}
//添加多条数据到无限列表,当然也支持单条添加
InfiniteList.AddDatas(datas);
}
/// <summary>
/// 随机组合一个姓名
/// </summary>
private string RandomName()
{
int surname = Random.Range(0, _surnames.Length);
int name = Random.Range(0, _names.Length);
return _surnames[surname] + _names[name];
}
运行场景,可以看到1000条数据的视图中,无论怎么滚动,真实存在的元素对象只有可见区域中的几个,视图滚动时,他们轮番被对象池提取、回收:
水平排列模式类似:
移除数据
目前无限列表只支持动态移除数据,在元素类中有一句代码将移除数据的逻辑绑定到移除
按钮上,当有数据被移除时,列表会自动刷新位置:
RemoveButton.onClick.AddListener(() => { _scrollRect.RemoveData(_data); });
清空数据
使用如下方式清空所有数据:
InfiniteList.ClearData();