Unity UGUI无限列表(Infinite List)

本文详细介绍了如何使用Unity的UGUI系统实现一个基于ScrollRect的InfiniteList,这种列表能够在滚动时动态加载和回收元素,有效减少内存和DrawCall。内容包括创建InfiniteListScrollRect、数据类和元素类的重写、元素模板的编辑、数据的添加与移除以及清空数据的方法。通过这种方式,可以实现高效地展示大量数据,尤其适用于游戏开发或大型应用中的列表滚动场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

更新日期:2020年10月16日。
Github源码:[点我获取源码]

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();
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

神码编程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值