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

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

猜你喜欢

转载自blog.csdn.net/qq_33205561/article/details/130060476