Unity中的超级Listview:带缓冲池,支持多类型cell,支持收缩,支持平铺,支持Right2Left。

之前写过一个带缓冲池的listview,时隔一年今天给大家再分享一个更加强大的listv。all in one,one for all!

来不及解释了,先贴个代码,函数名自注释,希望大家能看明白。
ListView类:

using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using UnityEngine.EventSystems;
using System;
using System.Collections.Generic;
using DG.Tweening;

//create by YJX
public class ListView : MonoBehaviour
{
    public Action OnDataFillCompleted;

    [SerializeField]
    private GameObject[] prefabs;

    [SerializeField]
    private float space;

    [SerializeField]
    private bool isManualFill = false;

    [SerializeField]
    private bool left2Right = true;

    [SerializeField]
    private float bufferFactor = 0.2f;

    [SerializeField]
    private int constrain = 1;

    private ScrollRect scrollRect;

    private RectTransform scrollRectTransform;

    private RectTransform rectTransform;

    private Vector2[] cellSizes;

    private List<ListViewCell>[] buffersArray;

    private Dictionary<int, CellInfo> cellInfoMapper = new Dictionary<int, CellInfo>();

    private Vector2 viewPortSize;

    private float visualDIA;

    private int CellsCount
    {
        get
        {
            return this.Adapter.GetCount();
        }
    }

    [SerializeField]
    private ListViewAdapter adapter;

    public ListViewAdapter Adapter
    {
        get
        {
            return adapter;
        }
        set
        {
            adapter = value;
            if (Application.isPlaying && this.gameObject.activeInHierarchy == true && isManualFill)
            {
                adapter.listview = this;
                Adapter.Initialize();
                Initialize();
            }
        }
    }

    // Use this for initialization
    protected void OnEnable()
    {
        if (Application.isPlaying && this.Adapter != null && !isManualFill)
        {
            Adapter.Initialize();
            Initialize();
        }
    }

    private void Initialize(Action onComplete = null)
    {
        if (!CheckConfigAndData())
        {
            return;
        }

        //ClearAllCell();

        this.rectTransform = transform.GetComponent<RectTransform>();
        this.scrollRectTransform = transform.parent.GetComponent<RectTransform>();
        this.scrollRect = this.scrollRectTransform.GetComponent<ScrollRect>();
        this.viewPortSize = this.scrollRectTransform.sizeDelta;

        this.cellSizes = new Vector2[this.prefabs.Length];
        for (int i = 0; i < this.prefabs.Length; i++)
        {
            RectTransform cellRect = this.prefabs[i].GetComponent<RectTransform>();
            this.cellSizes[i] = cellRect.sizeDelta;
        }

        if (this.scrollRect.horizontal)
        {
            this.visualDIA = (0.5f + this.bufferFactor) * this.viewPortSize.x;
        }
        else if (this.scrollRect.vertical)
        {
            this.visualDIA = (0.5f + this.bufferFactor) * this.viewPortSize.y;
        }

        GenerateCellBuffers();

        cellInfoMapper.Clear();

        //TODO
        //ForceRecycleAllBuffers();

        CalculateSizeAndCellPos(0f);

        this.scrollRect.onValueChanged.AddListener(FillData);

        FillData(Vector2.zero);

        if (OnDataFillCompleted != null)
        {
            OnDataFillCompleted();
        }
    }

    private bool CheckConfigAndData()
    {
        bool checkOk = true;
        if (this.constrain > 1 && this.AnyTitleCell())
        {
            Debug.LogError(string.Format("ListView:{0},this.constrain > 1 && have title cell", transform.name));
            checkOk = false;
        }
        return checkOk;
    }

    private bool AnyTitleCell()
    {
        bool isTitle = false;
        for (int i = 0; i < this.CellsCount; )
        {
            if (this.Adapter.IsTitleCell(i))
            {
                isTitle = true;
                break;
            }
            i += this.constrain;
        }

        return isTitle;
    }

    private void ClearAllCell()
    {
        int childCount = this.transform.childCount;

        for (int i = 0; i < childCount; i++)
        {
            GameObject.Destroy(this.transform.GetChild(i).gameObject);
        }
    }

    public void ReFillData()
    {
        ForceRecycleAllBuffers();
        CalculateSizeAndCellPos(BeyondDistance());
        FillData(Vector2.zero);

        if (OnDataFillCompleted != null)
        {
            OnDataFillCompleted();
        }
    }

    public void RefreshData()
    {
        ForceRecycleAllBuffers();
        CalculateSizeAndCellPos(BeyondDistance());
        FillData(Vector2.zero);
    }

    private 
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值