using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class Mall
{
public Sprite sprite;//贴图
public string ModelName = "";//模型名字
public string GoodsMessage = "";//物品介绍
//toto
}
public class UILoopListEzample : MonoBehaviour
{
public int ItemAmount;
public UILoopList uiList;
// Use this for initialization
void Start()
{
uiList.onSelectedEvent = OnSelectedEventHandler;
List<int> listData = new List<int>();
for (int i = 0; i < ItemAmount; i++)
{
listData.Add(i);
}
uiList.Data(listData);
}
private void OnSelectedEventHandler(UILoopItem item)
{
Debug.LogError("选择的单元数据为:" + item.GetData().ToString());
}
}
------------------------------------======================-------------------------------
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class UILoopItem : MonoBehaviour
{
[System.NonSerialized]
public int itemIndex;//当前数据第几个
[System.NonSerialized]
public GameObject itemObject;
private object data;
private Mall Mall_;
public void UpdateItem(int index, GameObject item)//(object mall,int index, GameObject item)
{
itemIndex = index;
itemObject = item;
}
public virtual void Data(object data)
{
this.data = data;
transform.Find("Text").GetComponent<Text>().text = "数据" + data.ToString();
}
public virtual object GetData()
{
return data;
}
public virtual void SetSelected(bool selected)
{
}
}
----------------------------------========================-------------------------------
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;
public class UILoopList : MonoBehaviour
{
/// <summary>
/// 滚动的方向
/// </summary>
enum Direction
{
Horizontal,//水平方向
Vertical//垂直方向
}
/// <summary>
/// 离上边的距离
/// </summary>
[SerializeField]
private float topPadding = 0;
/// <summary>
/// 离下边的距离
/// </summary>
[SerializeField]
private float bottomPadding = 0;
/// <summary>
///time框
/// </summary>
[SerializeField]
private RectTransform m_Cell;
[SerializeField]
private Vector2 m_Page = new Vector2(1, 1);//必须设置;几行几列
[SerializeField]
Direction direction = Direction.Horizontal;
[SerializeField, Range(4, 10)]
private int m_BufferNo;//Item的数量
/// <summary>
/// Item的间隔
/// </summary>
[SerializeField]
private float cellGapX = 0f;
[SerializeField]
private float cellGapY = 0f;
public delegate void OnSelectedEvent(UILoopItem item);
/// <summary>
/// 选择事件 但组件上一定要有Button组件 设置要在Data()设置数据前
/// </summary>
public OnSelectedEvent onSelectedEvent;//
private List<RectTransform> m_InstantiateItems = new List<RectTransform>();
private List<RectTransform> m_oldItems = new List<RectTransform>();
/// <summary>
/// Time的实际数量就是数字
/// </summary>
private IList m_Datas;
/// <summary>
/// 调整Item的间隔
/// </summary>
public Vector2 CellRect
{
get
{
return m_Cell != null ? new Vector2(cellGapX + m_Cell.sizeDelta.x, cellGapY + m_Cell.sizeDelta.y) : new Vector2(100, 100);
}
}
/// <summary>
/// 调整Item的间隔返回的是X 还是 Y
/// </summary>
public float CellScale { get { return direction == Direction.Horizontal ? CellRect.x : CellRect.y; } }
private float m_PrevPos = 0;
// 返回的是Content距离锚点的距离 x或y
public float DirectionPos { get { return direction == Direction.Horizontal ? m_Rect.anchoredPosition.x : m_Rect.anchoredPosition.y; } }
private int m_CurrentIndex;//页面的第一行(列)在整个conten中的位置
private Vector2 m_InstantiateSize = Vector2.zero;
public Vector2 InstantiateSize
{
get
{
if (m_InstantiateSize == Vector2.zero)
{
float rows, cols;
if (direction == Direction.Horizontal)
{
rows = m_Page.x;
cols = m_Page.y + (float)m_BufferNo;
}
else
{
rows = m_Page.x + (float)m_BufferNo;
cols = m_Page.y;
}
// 5 1
m_InstantiateSize = new Vector2(rows, cols);
}
return m_InstantiateSize;
}
}
/// <summary>
/// 返回的是行数成于列数
/// </summary>
public int PageCount { get { return (int)m_Page.x * (int)m_Page.y; } }
public int PageScale { get { return direction == Direction.Horizontal ? (int)m_Page.x : (int)m_Page.y; } }//返回的是几行几列
private ScrollRect m_ScrollRect;
private RectTransform m_Rect;
public int InstantiateCount { get { return (int)InstantiateSize.x * (int)InstantiateSize.y; } }
protected void Awake()
{
m_ScrollRect = GetComponentInParent<ScrollRect>();
m_ScrollRect.horizontal = direction == Direction.Horizontal;//滚动方向是否是垂直
m_ScrollRect.vertical = direction == Direction.Vertical;//滚动方向是否是水平
m_Rect = GetComponent<RectTransform>();
if (m_Cell.transform.parent != null)
m_Cell.gameObject.SetActive(false);//隐藏第一个Item面板
m_Rect.anchorMax = Vector2.zero;//设置中心点Content
m_Rect.anchorMin = Vector2.zero;//设置锚点Content
m_Rect.pivot = Vector2.zero;//它在这个RectTransform中旋转的标准化位置。
m_Rect.anchoredPosition = new Vector2(0f, 0f);//相对于锚点的位置设置为0,0
}
/// <summary>
/// 设置数据 数据格式为IList
/// </summary>
/// <param name="data">Data.</param>
public void Data(object data)
{
Reset();
m_Datas = data as IList;
if (m_Datas.Count > PageCount)//item数量是否大于 行成于列
{
//to
setBound(getRectByNum(m_Datas.Count));//构建滑动框的大小
}
else
{
setBound(m_Page);
}
if (m_Datas.Count > InstantiateCount)//是否Item数量大于 tiem数量加上行的数量
{
// print(m_Datas.Count+" "+InstantiateCount );
//toto
while (m_InstantiateItems.Count < InstantiateCount)
{
createItem(m_InstantiateItems.Count);//在这里生成的五个
}
}
else
{
while (m_InstantiateItems.Count > m_Datas.Count)
{
removeItem(m_InstantiateItems.Count - 1);
}
while (m_InstantiateItems.Count < m_Datas.Count)
{
createItem(m_InstantiateItems.Count);
}
}
if (m_Datas.Count > 0)
{
int count = Mathf.Min(m_InstantiateItems.Count, m_Datas.Count);
for (int i = 0; i < count; i++)
{
updateItem(i, m_InstantiateItems[i].gameObject);
}
}
}
private void Reset()
{
for (int i = 0; i < m_InstantiateItems.Count; i++)
{
m_InstantiateItems[i].gameObject.SetActive(false);
m_oldItems.Add(m_InstantiateItems[i]);
}
m_InstantiateItems.Clear();
m_PrevPos = 0;
m_CurrentIndex = 0;
selectedObject = null;
selectedItem = null;
this.GetComponent<RectTransform>().anchoredPosition = new Vector2(0f, 0);
}
public void SetIndexToBottom(int itemIndex)
{
this.GetComponent<RectTransform>().anchoredPosition = new Vector2(0f, CellRect.y * itemIndex - m_ScrollRect.GetComponent<RectTransform>().sizeDelta.y + CellRect.y * 2 + topPadding + bottomPadding);
}
private void createItem(int index)//0
{
RectTransform item = null;
if (m_oldItems.Count > 0)
{
item = m_oldItems[0];
m_oldItems.Remove(item);
}
else
{
item = GameObject.Instantiate(m_Cell);
item.SetParent(transform, false);
item.anchorMax = Vector2.zero;
item.anchorMin = Vector2.zero;
item.pivot = Vector2.zero;
}
item.name = "item" + index;
item.anchoredPosition = getPosByIndex(index);
// print(getPosByIndex(index));
m_InstantiateItems.Add(item);//添加进集合中
item.gameObject.SetActive(true);
//updateItem(index, item.gameObject);
}
private void removeItem(int index)
{
RectTransform item = m_InstantiateItems[index];
m_InstantiateItems.Remove(item);
item.gameObject.SetActive(false);
m_oldItems.Add(item);
//RectTransform.Destroy(item.gameObject);
}
/// <summary>
/// 由格子数量获取多少行多少列
/// </summary>
/// <param name="num"></param>格子个数
/// <returns></returns>
private Vector2 getRectByNum(int num)
{
return direction == Direction.Horizontal ?
new Vector2(m_Page.x, Mathf.CeilToInt(num / m_Page.x)) :
new Vector2(Mathf.CeilToInt(num / m_Page.y), m_Page.y);
}
/// <summary>
/// 设置Content的大小
/// </summary>
/// <param name="rows"></param>行数
/// <param name="cols"></param>列数
private void setBound(Vector2 bound)
{
// Debug.Log(bound.y * CellRect.x+":X");Debug.Log(bound.x * CellRect.y + bottomPadding + topPadding + ":Y");
m_Rect.sizeDelta = new Vector2(bound.y * CellRect.x, bound.x * CellRect.y + bottomPadding + topPadding);
}
public float MaxPrevPos
{
get
{
float result;
Vector2 max = getRectByNum(m_Datas.Count);
if (direction == Direction.Horizontal)
{
result = max.y - m_Page.y;
}
else
{
result = max.x - m_Page.x;
}
return result * CellScale;
}
}
public float scale { get { return direction == Direction.Horizontal ? 1f : -1f; } }//是横向就是1不是为-1
private bool isFirst = true;
void Update()
{
if (isFirst == true)
{
isFirst = false;
return;
}
//1或-1 ×与 X或Y -0
while (scale * DirectionPos - m_PrevPos < -CellScale * 2)
{
//Debug.Log(scale.ToString() + " " + DirectionPos.ToString() + " " + m_PrevPos.ToString() + "_____________" + -CellScale * 2);
if (m_PrevPos <= -MaxPrevPos) return;
m_PrevPos -= CellScale;
List<RectTransform> range = m_InstantiateItems.GetRange(0, PageScale);
m_InstantiateItems.RemoveRange(0, PageScale);
m_InstantiateItems.AddRange(range);
for (int i = 0; i < range.Count; i++)
{
moveItemToIndex(m_CurrentIndex * PageScale + m_InstantiateItems.Count + i, range[i]);
}
m_CurrentIndex++;
}
while (scale * DirectionPos - m_PrevPos > -CellScale)
{
// Debug.Log(scale.ToString() + " " + DirectionPos.ToString() + " " + m_PrevPos.ToString() + "_____________" + -CellScale);
if (Mathf.RoundToInt(m_PrevPos) >= 0) return;
m_PrevPos += CellScale;
m_CurrentIndex--;
if (m_CurrentIndex < 0) return;
List<RectTransform> range = m_InstantiateItems.GetRange(m_InstantiateItems.Count - PageScale, PageScale);
m_InstantiateItems.RemoveRange(m_InstantiateItems.Count - PageScale, PageScale);
m_InstantiateItems.InsertRange(0, range);
for (int i = 0; i < range.Count; i++)
{
moveItemToIndex(m_CurrentIndex * PageScale + i, range[i]);
}
}
}
private void moveItemToIndex(int index, RectTransform item)
{
item.anchoredPosition = getPosByIndex(index);
updateItem(index, item.gameObject);
}
/// <summary>
/// 初始化间距位置
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
private Vector2 getPosByIndex(int index)
{
return direction == Direction.Horizontal ?
new Vector2(Mathf.Floor(index / InstantiateSize.x) * CellRect.x, -(index % InstantiateSize.x) * CellRect.y) :
new Vector2((index % InstantiateSize.y) * CellRect.x, -Mathf.Floor(index / InstantiateSize.y) * CellRect.y - topPadding);
//float x, y;
//if(direction == Direction.Horizontal)
//{
// x = index % m_Page.x;
// y = Mathf.FloorToInt(index / m_Page.x);
//}
//else
//{
// x = Mathf.FloorToInt(index / m_Page.y);
// y = index % m_Page.y;
//}
//return new Vector2(y * CellRect.x, -x * CellRect.y);
}
private object selectedObject = null;
[System.NonSerialized]
public UILoopItem selectedItem = null;
private void updateItem(int index, GameObject item)
{
item.SetActive(index < m_Datas.Count);
if (item.activeSelf)
{
UILoopItem lit = item.GetComponent<UILoopItem>();
lit.UpdateItem(index, item);
lit.Data(m_Datas[index]);//打印函数
Debug.Log(selectedObject + " 666 " + m_Datas[index]);
if (selectedObject == m_Datas[index])
{
lit.SetSelected(true);
}
else
{
lit.SetSelected(false);
}
//该BUtton在列表中的索引
if (lit.GetComponent<Button>() != null && onSelectedEvent != null && addClickEventList.IndexOf(lit.GetComponent<Button>()) < 0)
{
addClickEventList.Add(lit.GetComponent<Button>());
lit.GetComponent<Button>().onClick.AddListener(delegate ()
{
if (onSelectedEvent != null)
{
if (selectedItem != null && selectedItem != item.GetComponent<UILoopItem>())
{
selectedItem.SetSelected(false);
}
selectedItem = item.GetComponent<UILoopItem>();
selectedObject = selectedItem.GetData();
selectedItem.SetSelected(true);
onSelectedEvent(selectedItem);
}
});
}
}
}
private List<Button> addClickEventList = new List<Button>();
/// <summary>
/// 选中的对象
/// </summary>
/// <returns></returns>
public object GetSelectedData()
{
return selectedObject;
}
/// <summary>
/// 设置选中对象
/// </summary>
/// <param name="selectedIndex"></param>
public void SetSelectedIndex(int selectedIndex)
{
if (m_Datas.Count > 0 && m_Datas.Count > selectedIndex)
{
selectedObject = m_Datas[selectedIndex];
if (selectedItem != null)
{
selectedItem.SetSelected(false);
}
for (int i = 0; i < m_InstantiateItems.Count; i++)
{
if (selectedObject == m_InstantiateItems[i].GetComponent<UILoopItem>().GetData())
{
m_InstantiateItems[i].GetComponent<UILoopItem>().SetSelected(true);
selectedItem = m_InstantiateItems[i].GetComponent<UILoopItem>();
}
}
}
}
}