【Unity】一个简单的无限列表

3 篇文章 0 订阅

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
{
 
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值