Unity无限循环滑动

using UnityEngine;
using System.Collections.Generic;
using UnityEngine.Events;


public class ItemCell : object
{


public GameObject item; 
public int _index;
}


public class ScrollRectList : MonoBehaviour
{
public enum Arrangement { Horizontal, Vertical, }
public Arrangement _movement = Arrangement.Horizontal;
//单行或单列的Item数量
[Range(1, 20)]
public int maxPerLine = 2;
//Item之间的距离
[Range(0, 20)]
public int cellPadiding = 5;
//Item的宽高
public int cellWidth = 100;
public int cellHeight = 100;


public Vector3 scale = Vector3.one;
//默认加载的行数,一般比可显示行数大2~3行
[Range(0, 20)]
public int viewCount = 3;
//public GameObject itemPrefab;
public RectTransform _content;


//记录当前滑动行列序号
private int _index = -1;
private List<ItemCell> _itemList;
private int _dataCount;


//public int getItemIndex(ItemCell o);
//public GetItemIndex getItemIndex;
public delegate void UpdateItem(ItemCell o, int index);
public UpdateItem updateItem;
public delegate void CreateItemobject(int index, UnityAction<GameObject> action);
public CreateItemobject createitemobject;
//public  void setItemIndex(ItemCell o,int index);
//public SetItemIndex setItemIndex;
public delegate void DeleteItemobject(ItemCell o);
public DeleteItemobject deleteitemobject;


public delegate void InitAfter();
public InitAfter initafter;


//道具是否是同一类型
public delegate bool ISsynchysis(int oldIndex,int nowIndex);
public ISsynchysis issynchysis;
//缓存池
public List<ItemCell> PoolItems  = new List<ItemCell>();
//public GameObject panelist;


void Start()
{
this._content.anchorMin = new Vector2 (0,1);
this._content.anchorMax = new Vector2 (0,1);
this._content.pivot = new Vector2 (0,1);
}
public int DataCount
{
get { return _dataCount; }
set
{
_dataCount = value;
UpdateTotalWidth();
}
}
void setItemIndex(ItemCell itemcell,int value)
{
itemcell._index = value;
itemcell.item.transform.localPosition = GetPosition(value);
//print ("4444=="+itemcell.item.transform.position);


}
public int getItemIndex(ItemCell itemcell)
{
return itemcell._index;
}


public void Init(int DataCount)
{
//this._content = panelist.GetComponent<RectTransform>();


DestroyAllItems ();
_index = -1;
_itemList = new List<ItemCell>();
this.DataCount = DataCount;


OnValueChange(Vector2.zero);
if(initafter != null)
initafter();
}


List<ItemCell > hideitems  = new List<ItemCell>();
public void OnValueChange(Vector2 pos)
{


if (_itemList == null) 
return;


int index = GetPosIndex();
// if(issynchysis!=null)
// Debug.Log("index:"+index+",list:"+_itemList.Count+"\n");


if (_index != index && index > -1)
{
_index = index;




//计算不显示对象
for (int i = 0;i < _itemList.Count;i++)
{
ItemCell item = _itemList[i];
int itemIndex = getItemIndex(item);
if (itemIndex < index * maxPerLine || (itemIndex >= (index + viewCount) * maxPerLine))
hideitems.Add(item);
}
foreach(ItemCell o in hideitems)
_itemList.Remove(o);


//Debug.Log("index:" + index + ",hideitems:" + hideitems.Count);


//计算显示对象
for (int i = _index * maxPerLine; i < (_index + viewCount) * maxPerLine; i++)
{
if (i < 0) 
continue;
if (i > _dataCount - 1) 
continue;
if (_itemList.Find(delegate(ItemCell item) { return getItemIndex(item) == i; }) == null)
{
if (hideitems.Count > 0)
{
//Debug.Log("get old imte :" + i);
bool issys = false;
if (issynchysis != null)
{
issys = issynchysis(hideitems[0]._index, i);
}
if (!issys)
{
ItemCell o = hideitems[0];
hideitems.Remove(o);
_itemList.Add(o);
setItemIndex(o, i);
updateItem(o, i);
}
else
{
GameObject.Destroy(hideitems[0].item);
hideitems.RemoveAt(0);
CreateItem(i);
}




}
else if (PoolItems.Count > 0)
{
//Debug.Log("get old pool :" + i);
ItemCell o = PoolItems[0];
o.item.SetActive(true);
PoolItems.RemoveAt(0);
_itemList.Add(o);
setItemIndex(o, i);
updateItem(o, i);
}
else
{
//print("create i:" + i + "\n");
CreateItem(i);
}
}
}


}
else
{
//_content.position = Vector3.zero;
}
foreach( ItemCell item in this.PoolItems)
{
GameObject.Destroy(item.item);
}
this.PoolItems.Clear();
}


/// <summary>
/// 提供给外部的方法,添加指定位置的Item
/// </summary>
public void AddItem(int index)
{
if (index > _dataCount||index<0)
{
Debug.LogError("添加错误:" + index);
return;
}


AddItemIntoPanel(index); 
DataCount += 1;


}


/// <summary>
/// 提供给外部的方法,删除指定位置的Item
/// </summary>
public void DelItem(int index)
{
if (index < 0 || index > _dataCount - 1)
{
Debug.LogError("删除错误:" + index);
return;
}
DataCount -= 1;
DelItemFromPanel(index);


}


private void AddItemIntoPanel(int index)
{
for (int i = 0; i < _itemList.Count; i++)
{


ItemCell item = _itemList[i];
int itemIndex = getItemIndex(item);


if (itemIndex >= index) 
this.setItemIndex(item,itemIndex + 1);
}
CreateItem(index);
}


private void DelItemFromPanel(int index)
{
int maxIndex = -1;
int minIndex = int.MaxValue;
List<ItemCell> delitems = new List<ItemCell>();
for (int i = 0;i < _itemList.Count; i++)
{
ItemCell item = _itemList[i];
int itemIndex = getItemIndex(item);


if (itemIndex == index)
{
//GameObject.Destroy(item.gameObject);
//GameObject.Destroy(item.gameObject);
//deleteitemobject(item);


//_itemList.Remove(item);
delitems.Add(item);
}
if (itemIndex> maxIndex)
{
maxIndex = itemIndex;
}
if (itemIndex < minIndex)
{
minIndex = itemIndex;
}
if (itemIndex > index)
{
setItemIndex(item,itemIndex-1);
}
}


foreach(ItemCell item in delitems)
{
_itemList.Remove(item);
GameObject.Destroy(item.item);//GameObject.Destroy(item.gameObject);
}
if (maxIndex < DataCount - 1)
{
CreateItem(maxIndex);
}
}


private void CreateItem(int index)
{
createitemobject(index, (obj) =>
{
if (obj != null)
{
obj.transform.SetParent(this._content.transform);
obj.GetComponent<RectTransform>().pivot = new Vector2(0f, 1f);
obj.GetComponent<RectTransform>().sizeDelta = new Vector2(this.cellWidth, this.cellHeight);
obj.transform.localScale = this.scale;
ItemCell itemcell = new ItemCell();
itemcell._index = index;
itemcell.item = obj;
setItemIndex(itemcell, index);
updateItem(itemcell, index);
_itemList.Add(itemcell);
}
});


}




public void UpdateItemCells()
{
if (_itemList != null)
{
for (int i = 0; i < _itemList.Count; i++)
{
ItemCell item = _itemList[i];
updateItem(item, item._index);
}   
}
}
private int GetPosIndex()
{


switch (_movement)
{
case Arrangement.Horizontal:
if(_content.anchoredPosition.x > 0)
return 0;
return Mathf.FloorToInt(_content.anchoredPosition.x / -(cellWidth * scale.x + cellPadiding));
case Arrangement.Vertical:
if( _content.anchoredPosition.y < 0 )
return 0;
return Mathf.FloorToInt(_content.anchoredPosition.y / (cellHeight * scale.y + cellPadiding));
}
return 0;
}


public Vector3 GetPosition(int i)
{
switch (_movement)
{
case Arrangement.Horizontal:
return new Vector3(cellWidth * scale.x * (i / maxPerLine) + cellPadiding, -(cellHeight * scale.y + cellPadiding) * (i % maxPerLine), 0f);
case Arrangement.Vertical:
//增加列表居中对齐计算
float leftrightspace = 0;
leftrightspace = (_content.sizeDelta.x - cellWidth * scale.x * maxPerLine - cellPadiding * maxPerLine * 2) / 2;
if(leftrightspace < 0 )
leftrightspace = 0;
else if(leftrightspace > cellPadiding)
leftrightspace = leftrightspace - cellPadiding;
else
leftrightspace = 0;


return new Vector3(leftrightspace + cellWidth * scale.x * (i % maxPerLine) + (i % maxPerLine) * cellPadiding + cellPadiding, -(cellHeight * scale.y + cellPadiding) * (i / maxPerLine) - cellPadiding, 0f);
}
return Vector3.zero;
}




private void UpdateTotalWidth()
{
int lineCount = Mathf.CeilToInt((float)_dataCount / maxPerLine);
switch (_movement)
{
case Arrangement.Horizontal:
_content.sizeDelta = new Vector2(cellWidth * scale.y * lineCount + cellPadiding * (lineCount - 1), _content.sizeDelta.y);
break;
case Arrangement.Vertical:
_content.sizeDelta = new Vector2(_content.sizeDelta.x, cellHeight * scale.y * lineCount + cellPadiding * (lineCount + 2));
break;
}
//_content.localPosition = Vector3.zero;


}




public void DestroyAllItems()
{
if (_itemList == null)
{
return;
}


if (issynchysis == null)
{
foreach (ItemCell item in this._itemList)

if(item.item !=null)
{
PoolItems.Add(item);
item.item.SetActive(false);
}
}
}
else

foreach(ItemCell item in this._itemList)
{
GameObject.Destroy(item.item);
}
}


foreach(ItemCell item in this.hideitems)
{
if (item.item != null)
{
GameObject.Destroy(item.item);
}
}
this.hideitems.Clear();
_itemList = null;
}


public void Destroy()
{
DestroyAllItems ();
foreach( ItemCell item in this.PoolItems)
{
GameObject.Destroy(item.item);
}
this.PoolItems.Clear();
}


public ItemCell GetItemByIndex(int index)
{
for (int i = 0;i < _itemList.Count;i++)
{
ItemCell item = _itemList[i];
int itemIndex = getItemIndex(item);
if (itemIndex == index)
return item;


}
return null;
}
    public Vector3 GetIndexPos(int index)
    {
        if (index > 0)
        {
            switch (_movement)
            {
                case Arrangement.Horizontal:
                    return new Vector3(-cellWidth * scale.x * (index / maxPerLine) + cellPadiding, -(cellHeight * scale.y + cellPadiding) * (index % maxPerLine), 0f);
                case Arrangement.Vertical:
                    //增加列表居中对齐计算
                    float leftrightspace = 0;
                    leftrightspace = (_content.sizeDelta.x - cellWidth * scale.x * maxPerLine - cellPadiding * maxPerLine * 2) / 2;
                    if (leftrightspace < 0)
                        leftrightspace = 0;
                    else if (leftrightspace > cellPadiding)
                        leftrightspace = leftrightspace - cellPadiding;
                    else
                        leftrightspace = 0;


                    return new Vector3(0f, (cellHeight * scale.y + cellPadiding) * (index / maxPerLine) - cellPadiding, 0f);
            }
        }
        return Vector3.zero;
    }
public void PrintList()
{
foreach (ItemCell icell in _itemList)
{
Debug.LogError("Item Name: " + icell.item.name + ", Index: " + icell._index);
}
}

}




using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using UnityEngine.Events;
public class Test : MonoBehaviour {
    [SerializeField]
    ScrollRectList myScrollRect;
    [SerializeField]
    ScrollRect scrollRect;
    [SerializeField]
    GameObject rankItem;
    // Use this for initialization
    void Start () {
        InitScroll();
    }

// Update is called once per frame
void Update () {

}
    void InitScroll()
    {
        scrollRect.onValueChanged.AddListener(OnValueChange);
        myScrollRect.createitemobject = delegate (int index, UnityAction<GameObject> action)
        {
            if (rankItem != null)
            {
                GameObject cellObj = Instantiate(rankItem.gameObject);
                action(cellObj);
            }
        };
        myScrollRect.updateItem = delegate (ItemCell o, int index)
        {
            o.item.transform.FindChild("Text").GetComponent<Text>().text = index + "";
        };
        myScrollRect.Init(5000);
    }
    void OnValueChange(Vector2 pos)
    {
        myScrollRect.OnValueChange(pos);
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值