using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;
using UnityEngine.EventSystems;
[DisallowMultipleComponent]
public class UIWarpContent : MonoBehaviour
{
public delegate void OnInitializeItem(GameObject go, int dataIndex);
public OnInitializeItem onInitializeItem;
public delegate void OnInitializeItem1(Item item, int dataIndex);
public OnInitializeItem1 onInitializeItem1;
public enum Arrangement
{
Horizontal,
Vertical,
}
/// <summary>
/// Type of arrangement -- vertical or horizontal.
/// </summary>
public Arrangement arrangement = Arrangement.Vertical;
/// <summary>
/// Maximum children per line.
/// If the arrangement is horizontal, this denotes the number of columns.
/// If the arrangement is vertical, this stands for the number of rows.
/// </summary>
[Range(1, 50)]
public int maxPerLine = 1;
/// <summary>
/// The width of each of the cells.
/// </summary>
public float cellWidth = 200f;
/// <summary>
/// The height of each of the cells.
/// </summary>
public float cellHeight = 200f;
/// <summary>
/// The Width Space of each of the cells.
/// </summary>
[Range(0, 200)]
public float cellWidthSpace = 0f;
/// <summary>
/// The Height Space of each of the cells.
/// </summary>
[Range(0, 200)]
public float cellHeightSpace = 0f;
[Range(0, 30)]
public int viewCount = 5;
public ScrollRect scrollRect;
public RectTransform content;
public GameObject goItemPrefab;
private int dataCount;
private int curScrollPerLineIndex = -1;
private List<UIWarpContentItem> listItem = new List<UIWarpContentItem>();
private Queue<UIWarpContentItem> unUseItem = new Queue<UIWarpContentItem>();
public void Init(int dataCount)
{
if (scrollRect == null || content == null || goItemPrefab == null)
{
Debug.LogError("异常:请检测<" + gameObject.name + ">对象上UIWarpContent对应ScrollRect、Content、GoItemPrefab 是否存在值...." + scrollRect + " _" + content + "_" + goItemPrefab);
return;
}
scrollRect.onValueChanged.RemoveAllListeners();
if (dataCount > 0)
{
scrollRect.onValueChanged.AddListener(onValueChanged);
}
setDataCount(dataCount);
if (null != unUseItem) unUseItem.Clear();
if (null != listItem) listItem.Clear();
setUpdateRectItem(0);
}
public void RushData(int dataCount)
{
scrollRect.onValueChanged.RemoveAllListeners();
if (listItem.Count > 0)
{
for (int i = listItem.Count - 1; i >= 0; i--)
{
UIWarpContentItem item = listItem[i];
item.Index = -10;
listItem.Remove(item);
unUseItem.Enqueue(item);
}
}
if (dataCount > 0)
{
scrollRect.onValueChanged.AddListener(onValueChanged);
}
setDataCount(dataCount);
setUpdateRectItem(0);
}
public void ShowItem(int count)
{
if (arrangement == Arrangement.Vertical)
{
content.anchoredPosition = new Vector2(0, count * cellHeight);
}
else
{
content.anchoredPosition = new Vector2(count * cellWidth, 0);
}
}
public void setDataCount(int count)
{
if (dataCount == count)
{
return;
}
dataCount = count;
setUpdateContentSize();
}
private void onValueChanged(Vector2 vt2)
{
switch (arrangement)
{
case Arrangement.Vertical:
float y = vt2.y;
if (y >= 1.0f || y <= 0.0f)
{
// return;
}
break;
case Arrangement.Horizontal:
float x = vt2.x;
if (x <= 0.0f || x >= 1.0f)
{
return;
}
break;
}
int _curScrollPerLineIndex = getCurScrollPerLineIndex();
if (_curScrollPerLineIndex == curScrollPerLineIndex)
{
return;
}
setUpdateRectItem(_curScrollPerLineIndex);
}
/**
* @des:设置更新区域内item
* 功能:
* 1.隐藏区域之外对象
* 2.更新区域内数据
*/
private void setUpdateRectItem(int scrollPerLineIndex)
{
if (scrollPerLineIndex < 0)
{
return;
}
curScrollPerLineIndex = scrollPerLineIndex;
int startDataIndex = curScrollPerLineIndex * maxPerLine;
int endDataIndex = (curScrollPerLineIndex + viewCount) * maxPerLine;
if (listItem == null)
{
return;
}
//移除
for (int i = listItem.Count - 1; i >= 0; i--)
{
UIWarpContentItem item = listItem[i];
int index = item.Index;
if (index < startDataIndex || index >= endDataIndex)
{
item.Index = -10;
listItem.Remove(item);
unUseItem.Enqueue(item);
}
}
//显示
for (int dataIndex = startDataIndex; dataIndex < endDataIndex; dataIndex++)
{
if (dataIndex >= dataCount)
{
continue;
}
if (isExistDataByDataIndex(dataIndex))
{
continue;
}
createItem(dataIndex);
}
}
public float getViewItemSize
{
get
{
return cellHeight + cellHeightSpace;
}
}
public void UpdateViewCount(int count)
{
viewCount = count;
setUpdateRectItem(viewCount);
}
/**
* @des:添加当前数据索引数据
*/
public void AddItem(int dataIndex)
{
if (dataIndex < 0 || dataIndex > dataCount)
{
Debug.Log("过滤了!" + "dataIndex = " + dataIndex + " | dataCount = " + dataCount);
return;
}
//检测是否需添加gameObject
bool isNeedAdd = false;
for (int i = listItem.Count - 1; i >= 0; i--)
{
UIWarpContentItem item = listItem[i];
if (item.Index >= (dataCount - 1))
{
isNeedAdd = true;
break;
}
}
setDataCount(dataCount + 1);
if (isNeedAdd)
{
for (int i = 0; i < listItem.Count; i++)
{
UIWarpContentItem item = listItem[i];
int oldIndex = item.Index;
if (oldIndex >= dataIndex)
{
item.Index = oldIndex + 1;
}
}
setUpdateRectItem(getCurScrollPerLineIndex());
}
else
{
//重新刷新数据
//for (int i = 0; i < listItem.Count; i++) {
// UIWarpContentItem item = listItem [i];
// int oldIndex = item.Index;
// if (oldIndex>=dataIndex) {
// item.Index = oldIndex;
// }
// item = null;
//}
}
}
/**
* @des:添加当前数据索引数据
*/
public void UpdataItem(int dataIndex)
{
if (dataIndex < 0 || dataIndex > dataCount)
{
return;
}
if (isExistDataByDataIndex(dataIndex))
{
for (int i = 0; i < listItem.Count; i++)
{
if (listItem[i].Index == dataIndex)
{
listItem[i].Index = dataIndex;
break;
}
}
}
}
public UIWarpContentItem GetItem(int dataIndex)
{
if (dataIndex < 0 || dataIndex > dataCount)
{
return null;
}
if (isExistDataByDataIndex(dataIndex))
{
// UIWarpContentItem go = new UIWarpContentItem ();
for (int i = 0; i < listItem.Count; i++)
{
if (listItem[i].Index == dataIndex)
{
return listItem[i];
}
}
}
return null;
}
public void UpdataAllItem()
{
for (int i = 0; i < listItem.Count; i++)
{
int index = listItem[i].Index;
if (isExistDataByDataIndex(index))
{
listItem[i].Index = index;
}
}
}
/**
* @des:删除当前数据索引下数据
*/
public void DelItem(int dataIndex)
{
if (dataIndex < 0 || dataIndex >= dataCount)
{
return;
}
//删除item逻辑三种情况
//1.只更新数据,不销毁gameObject,也不移除gameobject
//2.更新数据,且移除gameObject,不销毁gameObject
//3.更新数据,销毁gameObject
bool isNeedDestroyGameObject = (listItem.Count >= dataCount);
setDataCount(dataCount - 1);
for (int i = listItem.Count - 1; i >= 0; i--)
{
UIWarpContentItem item = listItem[i];
int oldIndex = item.Index;
if (oldIndex == dataIndex)
{
listItem.Remove(item);
if (isNeedDestroyGameObject)
{
Destroy(item.gameObject);
}
else
{
item.Index = -1;
unUseItem.Enqueue(item);
}
}
if (oldIndex > dataIndex)
{
item.Index = oldIndex - 1;
}
}
setUpdateRectItem(getCurScrollPerLineIndex());
if (unUseItem.Count > 0)
{
UIWarpContentItem item = unUseItem.Dequeue();
Destroy(item.gameObject);
}
}
/**
* @des:获取当前index下对应Content下的本地坐标
* @param:index
* @内部使用
*/
public Vector3 getLocalPositionByIndex(int index)
{
float x = 0f;
float y = 0f;
float z = 0f;
switch (arrangement)
{
case Arrangement.Horizontal: //水平方向
x = (index / maxPerLine) * (cellWidth + cellWidthSpace);
y = -(index % maxPerLine) * (cellHeight + cellHeightSpace);
break;
case Arrangement.Vertical://垂着方向
x = (index % maxPerLine) * (cellWidth + cellWidthSpace) + cellWidth / 2 + cellWidthSpace / 2;
y = -(index / maxPerLine) * (cellHeight + cellHeightSpace) - cellHeight / 2 - cellHeightSpace / 2;
break;
}
return new Vector3(x, y, z);
}
/**
* @des:创建元素
* @param:dataIndex
*/
private void createItem(int dataIndex)
{
UIWarpContentItem item;
if (unUseItem.Count > 0)
{
item = unUseItem.Dequeue();
}
else
{
item = addChild(goItemPrefab, content).AddComponent<UIWarpContentItem>();
}
item.WarpContent = this;
item.Index = dataIndex;
listItem.Add(item);
}
/**
* @des:当前数据是否存在List中
*/
private bool isExistDataByDataIndex(int dataIndex)
{
if (listItem == null || listItem.Count <= 0)
{
return false;
}
for (int i = 0; i < listItem.Count; i++)
{
if (listItem[i].Index == dataIndex)
{
return true;
}
}
return false;
}
/**
* @des:根据Content偏移,计算当前开始显示所在数据列表中的行或列
*/
private int getCurScrollPerLineIndex()
{
switch (arrangement)
{
case Arrangement.Horizontal: //水平方向
return Mathf.FloorToInt(Mathf.Abs(content.anchoredPosition.x) / (cellWidth + cellWidthSpace));
case Arrangement.Vertical://垂着方向
int count = 0;
if (content.anchoredPosition.y <= 0)
{
return 0;
}
count = Mathf.FloorToInt(Mathf.Abs(content.anchoredPosition.y) / (cellHeight + cellHeightSpace));
if (count < 0)
{
count = 0;
}
else if (count > dataCount)
{
count = dataCount;
}
// return Mathf.FloorToInt(Mathf.Abs(content.anchoredPosition.y)/(cellHeight+cellHeightSpace));
return count;
}
return 0;
}
/**
* @des:更新Content SizeDelta
*/
private void setUpdateContentSize()
{
int lineCount = Mathf.CeilToInt((float)dataCount / maxPerLine);
switch (arrangement)
{
case Arrangement.Horizontal:
content.sizeDelta = new Vector2(cellWidth * lineCount + cellWidthSpace * (lineCount - 1), content.sizeDelta.y);
break;
case Arrangement.Vertical:
content.sizeDelta = new Vector2(content.sizeDelta.x, cellHeight * lineCount + cellHeightSpace * (lineCount - 1));
break;
}
}
private RectTransform _rectTransform;
private RectTransform rectTransform
{
get
{
if (_rectTransform == null)
{
_rectTransform = scrollRect.GetComponent<RectTransform>();
}
return _rectTransform;
}
}
/**
* @des:实例化预设对象 、添加实例化对象到指定的子对象下
*/
private GameObject addChild(GameObject goPrefab, Transform parent)
{
if (goPrefab == null || parent == null)
{
Debug.LogError("异常。UIWarpContent.cs addChild(goPrefab = null || parent = null)");
return null;
}
GameObject goChild = Instantiate(goPrefab);
goChild.layer = parent.gameObject.layer;
goChild.transform.SetParent(parent, false);
if (maxPerLine <= 1)
{
switch (arrangement)
{
case Arrangement.Horizontal:
goChild.transform.GetComponent<RectTransform>().sizeDelta = new Vector2(goChild.transform.GetComponent<RectTransform>().rect.width, rectTransform.rect.height);
break;
case Arrangement.Vertical:
goChild.transform.GetComponent<RectTransform>().sizeDelta = new Vector2(cellWidth, cellHeight);
break;
}
}
goChild.gameObject.SetActive(true);
return goChild;
}
public void ClearAllData()
{
scrollRect.onValueChanged.RemoveAllListeners();
if (listItem != null && listItem.Count > 0)
{
foreach (var item in listItem)
{
Destroy(item.gameObject);
}
//foreach (var item in unUseItem)
//{
// GameObject go = item.gameObject;
// Destroy(go);
//}
listItem.Clear();
if (null != unUseItem)
{
unUseItem.Clear();
}
onInitializeItem = null;
//重置上一次的操作位置
if (null != scrollRect.verticalScrollbar)
{
scrollRect.verticalScrollbar.value = 1;
}
//重置上一次的操作位置
if (null != scrollRect.horizontalScrollbar)
{
scrollRect.horizontalScrollbar.value = 1;
content.anchoredPosition = Vector2.zero;
}
}
if (content != null)
{
int childCount = content.transform.childCount;
for (int i = 0; i < childCount; i++)
{
Destroy(content.transform.GetChild(i).gameObject);
}
}
}
void OnDestroy()
{
scrollRect = null;
content = null;
goItemPrefab = null;
onInitializeItem = null;
listItem.Clear();
unUseItem.Clear();
}
}
using UnityEngine;
using System.Collections;
/***
*@des:warp下Element对应标记
*/
[DisallowMultipleComponent]
public class UIWarpContentItem : MonoBehaviour {
private int index;
private UIWarpContent warpContent;
private RectTransform mtransform;
private RectTransform mYtransform {
get
{
if (mtransform == null)
{
mtransform = transform.GetComponent<RectTransform>();
}
return mtransform;
}
}
void OnDestroy(){
warpContent = null;
}
public UIWarpContent WarpContent{
set{
warpContent = value;
}
}
public string getName()
{
return gameObject.name;
}
private Item item;
public Item getItem()
{
if (item == null)
item = gameObject.GetComponent<Item>();
return item;
}
public int Index {
set{
index = value;
mYtransform.localPosition = warpContent.getLocalPositionByIndex(index);
gameObject.name = index.ToString();
//(index<10)?("0"+index):(""+index);
if (warpContent.onInitializeItem1 != null && index>=0) {
warpContent.onInitializeItem1 (getItem(), index);
//Debug.Log("index = " + index);
}
}
get{
return index;
}
}
}