Unity——无限滚动复用列表

无限滚动复用列表


一、Demo展示

12


二、前言

游戏中有非常多的下拉滚动菜单,比如成就列表,任务列表,以及背包仓库之类;如果列表内容非常丰富,会占用大量内存,这篇无限滚动复用ScrollView就是解决这种问题;还可以用来做朋友圈,聊天等;

一般情况,ScrollView中每个Item的大小是一直的,使用ContentSizeFillter组件足够解决大部分问题;

如果每个Item大小不一致,问题就复杂起来,需要做滚动位置判断,我这里做了大小适应;


三、设计思路

1.将数据部分和滚动逻辑部分分离开,数据设计成泛型类;

2.在ScrollView组件上添加ScrollView脚本,控制Item的添加和删除,分为头部和尾部;

3.在每个Item上添加ScrollItem脚本,重写更新数据方法,同时监听自身是否为头部或者尾部;

4.如果为头部或者尾部,且超界通过委托调用ScrollView脚本中的添加或删除Item方法;


四、关键基类

1.ScrollData

负责整个列表的数据管理,分为总数据和现实数据两个链表,增删查改方法;泛型类方便复用;

这里使用LinkedList方便查找并返回头尾节点;

全部代码:

public class ScrollData<T>
{
    public List<T> allDatas;
    public LinkedList<T> curDatas;
    
    public ScrollData()
    {
        allDatas = new List<T>();
        curDatas = new LinkedList<T>();
        //加载数据;
    }

    //获取头数据
    public T GetHeadData()
    {
        if(allDatas.Count == 0)
            return default(T);

        if (curDatas.Count == 0)
        {
            T head = allDatas[0];
            curDatas.AddFirst(head);
            return head;
        }

        T t = curDatas.First.Value;
        int index = allDatas.IndexOf(t);

        if (index != 0)
        {
            T head = allDatas[index - 1];
            curDatas.AddFirst(head);
            return head;
        }
        return default(T);
    }

    //移出头数据
    public bool RemoveHeadData()
    {
        if (curDatas.Count == 0 || curDatas.Count == 1)
            return false;
        curDatas.RemoveFirst();
        return true;
    }

    //获取尾部数据
    public T GetEndData()
    {
        if (allDatas.Count == 0)
            return default(T);

        if (curDatas.Count == 0)
        {
            T end = allDatas[0];
            curDatas.AddLast(end);
            return end;
        }

        T t = curDatas.Last.Value;
        int index = allDatas.IndexOf(t);
        
        if (index != allDatas.Count - 1)
        {
            T end = allDatas[index + 1];
            curDatas.AddLast(end);
            return end;
        }
         
        return default(T);
    }
    
    //移出尾部数据
    public bool RemoveEndData()
    {
        if (curDatas.Count == 0 || curDatas.Count == 1)
            return false;
        curDatas.RemoveLast();
        return true;
    }

    //添加数据,通过数组
    public void AddData(T[] t)
    {
        allDatas.AddRange(t);
    }

    //添加数据,通过链表
    public void AddData(List<T> t)
    {
        allDatas.AddRange(t.ToArray()); 
    }
    
    //添加单条数据
    public void AddData(T t)
    {
        allDatas.Insert(0,t);
        curDatas.AddFirst(t
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小紫苏0

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

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

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

打赏作者

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

抵扣说明:

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

余额充值