之前写过一个带缓冲池的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