这里有更完善的版本
- 实测实现了一个10000条数据的Listview,sony z3真机瞬间完成初始化,滑动无比流畅。
- 下面的截图是实际项目中使用的效果,实例化三个cellPrefab作为缓冲池,改变它们的位置和数据填充来模拟一个数据长度为15的listview:
- 下面直接给出完整代码,函数命名简明,希望大家能看明白:
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using UnityEngine.EventSystems;
using System;
using System.Collections.Generic;
using Framework;
using DG.Tweening;
//create by YJX
public class AListView : LayoutGroup
{
private float visualDIA;
private int eachBufferCount;
private ScrollRect scrollRect;
private RectTransform scrollRectTransform;
[HideInInspector]
private Vector2[] cellSizes;
private List<IndexAndBuffer>[] buffersArray;
private List<IndexAndPos> cellsPosInfo = new List<IndexAndPos>();
private List<int> showingCells = new List<int>();//index
public Action OnDataFillCompleted;
[SerializeField]
private ListViewAdapter _adapter;
private float width;
private float height;
public GameObject[] prefabs;
public string mainCellname;
private float[] fixedHeightArray;
private int CellsCount
{
get
{
return this.Adapter.GetCount();
}
}
public bool isManualFill = false;
public float bufferFactor = 1f;
public ListViewAdapter Adapter
{
get
{
return _adapter;
}
set
{
_adapter = value;
if (isManualFill && this.gameObject.activeInHierarchy == true && Application.isPlaying)
{
_adapter.aListview = this;
if (isManualFill)
{
Adapter.Initialize();
Initialize();
}
}
}
}
// Use this for initialization
protected override void Start()
{
if (this.Adapter != null && !isManualFill && Application.isPlaying)
{
Adapter.Initialize();
Initialize();
}
}
public void Initialize(Action onComplete = null)
{
if (mainCellname != string.Empty)
{
string[] difCell = mainCellname.Split(',');
for (int i = 0; i < difCell.Length; i++)
{
prefabs[i] = Resources.Load<GameObject>(difCell[i]);
}
}
this.scrollRectTransform = transform.parent.GetComponent<RectTransform>();
this.scrollRect = this.scrollRectTransform.GetComponent<ScrollRect>();
this.fixedHeightArray = new float[this.CellsCount];
this.width = this.scrollRectTransform.sizeDelta.x;
this.height = this.scrollRectTransform.sizeDelta.y;
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;
}