475 lines
14 KiB
C#
475 lines
14 KiB
C#
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System;
|
|
using XLua;
|
|
|
|
public class UIContainerBase : UIBase
|
|
{
|
|
// 容器每个Item的内容和位置
|
|
public class ContentPos
|
|
{
|
|
public Vector2 Pos; // 位置
|
|
public object Obj; // 显示信息
|
|
public UIItemBase ShowItem; // 显示脚本 - 内包含和 Obj 一样的显示信息
|
|
}
|
|
|
|
void OnDisable()
|
|
{
|
|
_ContainerObj.anchoredPosition = Vector2.zero;
|
|
}
|
|
|
|
void OnEnable()
|
|
{
|
|
// 仅当Conten内容被重新设置过才执行初始化。
|
|
if (!_HasInit)
|
|
{
|
|
StartInitContainer();
|
|
}
|
|
}
|
|
|
|
#region calculate rect
|
|
|
|
protected float _ViewPortWidth = 0;
|
|
protected float _ViewPortHeight = 0;
|
|
protected float _ContentCanvasWidth = 0;
|
|
protected float _ContentCanvasHeight = 0;
|
|
protected int _ContentRow = 0;
|
|
protected int _ContentColumn = 0;
|
|
|
|
protected int _ShowRowCount = 0;
|
|
protected int _ShowColumnCount = 0;
|
|
|
|
public int _InitItemCount = 0;
|
|
private int _InitItemCountPrivate = 0;
|
|
|
|
private void CalculateRect(ICollection items)
|
|
{
|
|
int itemCount = items.Count;
|
|
|
|
_ViewPortWidth = _ScrollTransform.sizeDelta.x;
|
|
_ViewPortHeight = _ScrollTransform.sizeDelta.y;
|
|
|
|
_ContentColumn = 1;
|
|
_ContentRow = 1;
|
|
if (_LayoutGroup.constraint == GridLayoutGroup.Constraint.FixedRowCount)
|
|
{
|
|
_ContentColumn = _LayoutGroup.constraintCount;
|
|
_ContentRow = itemCount / _ContentColumn;
|
|
if (itemCount % _ContentColumn > 0)
|
|
{
|
|
++_ContentRow;
|
|
}
|
|
}
|
|
else if (_LayoutGroup.constraint == GridLayoutGroup.Constraint.FixedColumnCount)
|
|
{
|
|
_ContentRow = _LayoutGroup.constraintCount;
|
|
_ContentColumn = itemCount / _ContentRow;
|
|
if (itemCount % _ContentRow > 0)
|
|
{
|
|
++_ContentColumn;
|
|
}
|
|
}
|
|
|
|
_ValueList.Clear();
|
|
int i = 0;
|
|
var enumerator = items.GetEnumerator();
|
|
enumerator.Reset();
|
|
while (enumerator.MoveNext())
|
|
//for (int i = 0; i < itemCount; ++i)
|
|
{
|
|
int column = i / _ContentRow;
|
|
int row = i % _ContentRow;
|
|
|
|
var contentPos = new ContentPos();
|
|
contentPos.Pos = new Vector2(
|
|
row * (_LayoutGroup.cellSize.x + _LayoutGroup.spacing.x) + _LayoutGroup.cellSize.x * 0.5f,
|
|
-column * (_LayoutGroup.cellSize.y + _LayoutGroup.spacing.y) - _LayoutGroup.cellSize.y * 0.5f);
|
|
contentPos.Obj = enumerator.Current;
|
|
_ValueList.Add(contentPos);
|
|
|
|
++i;
|
|
}
|
|
|
|
|
|
_ContentCanvasWidth = _LayoutGroup.cellSize.x * _ContentRow + _LayoutGroup.spacing.x * (_ContentRow - 1);
|
|
_ContentCanvasHeight = _LayoutGroup.cellSize.y * _ContentColumn + _LayoutGroup.spacing.y * (_ContentColumn - 1);
|
|
|
|
if (_BG != null)
|
|
{
|
|
_BG.rectTransform.sizeDelta = new Vector2(_ContentCanvasWidth + 20, _ContentCanvasHeight + 20);
|
|
}
|
|
|
|
if (_ContainerBaseLarge)
|
|
{
|
|
_ContentCanvasWidth = Math.Max(_ScrollTransform.sizeDelta.x, _ContentCanvasWidth);
|
|
_ContentCanvasHeight = Math.Max(_ScrollTransform.sizeDelta.y, _ContentCanvasHeight);
|
|
}
|
|
|
|
_ShowRowCount = (int)Math.Ceiling((_ViewPortWidth + _LayoutGroup.spacing.x) / (_LayoutGroup.cellSize.x + _LayoutGroup.spacing.x));
|
|
_ShowColumnCount = (int)Math.Ceiling((_ViewPortHeight + _LayoutGroup.spacing.y) / (_LayoutGroup.cellSize.y + _LayoutGroup.spacing.y));
|
|
|
|
//_InitItemCount = _ShowColumnCount * _ShowRowCount;
|
|
//_InitItemCount = Math.Min(_InitItemCount, itemCount);
|
|
|
|
_ContainerObj.sizeDelta = new Vector2(_ContentCanvasWidth, _ContentCanvasHeight);
|
|
|
|
float containerPosX = 0;
|
|
float containerPosY = 0;
|
|
if (_ContainerObj.sizeDelta.x < _ScrollTransform.sizeDelta.x)
|
|
{
|
|
containerPosX = (_ScrollTransform.sizeDelta.x - _ContainerObj.sizeDelta.x) * 0.5f;
|
|
}
|
|
if (_ContainerObj.sizeDelta.y < _ScrollTransform.sizeDelta.y)
|
|
{
|
|
containerPosY = (_ContainerObj.sizeDelta.y - _ScrollTransform.sizeDelta.y) * 0.5f;
|
|
}
|
|
_ContainerObj.transform.localPosition = new Vector3(containerPosX, containerPosY, 0);
|
|
|
|
//LogModule.DebugLog("CalculateRect viewPortWidth:" + _ShowRowCount + "," + _ShowColumnCount + "," + _ContentCanvasWidth + "," + _ContentCanvasHeight);
|
|
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region
|
|
|
|
public Vector3 GetItemPosition(object item)
|
|
{
|
|
foreach (UIItemBase uiItem in _ItemPrefabList)
|
|
{
|
|
if (uiItem._InitInfo == item)
|
|
{
|
|
return uiItem.transform.position;
|
|
}
|
|
}
|
|
return Vector3.zero;
|
|
}
|
|
|
|
public Vector3 GetItemLocalPosition(UIItemBase item)
|
|
{
|
|
foreach (UIItemBase uiItem in _ItemPrefabList)
|
|
{
|
|
if (uiItem._InitInfo.Equals(item._InitInfo))
|
|
{
|
|
return uiItem.transform.localPosition;
|
|
}
|
|
}
|
|
return Vector3.zero;
|
|
}
|
|
|
|
#endregion
|
|
|
|
public ScrollRect _ScrollRect; // 滑动框组件
|
|
public RectTransform _ScrollTransform; // 滑动框组件Rt
|
|
public GridLayoutGroup _LayoutGroup; // 自动布局组件
|
|
public GameObject _ContainItemPre; // Item预设体
|
|
public RectTransform _ContainerObj; // 自身容器Rt
|
|
public Image _BG;
|
|
public bool _ContainerBaseLarge = false;
|
|
|
|
protected List<UIItemBase> _ItemPrefabList = new List<UIItemBase>();
|
|
protected List<ContentPos> _ValueList = new List<ContentPos>(); // 内容的数组
|
|
protected UIItemBase.ItemClick _OnClickItem; // 单个内容Item点击回调
|
|
protected UIItemBase.PanelClick _OnClickPanel; // ...
|
|
public int GetValueCnt()
|
|
{
|
|
return _ValueList.Count;
|
|
}
|
|
|
|
public void SetValueObjByIndex(int index, object initInfo)
|
|
{
|
|
if(index < _ValueList.Count)
|
|
{
|
|
_ValueList[index].Obj = initInfo;
|
|
_ItemPrefabList[index]._InitInfo = initInfo;
|
|
|
|
Hashtable param = new Hashtable();
|
|
param.Add("InitObj", initInfo);
|
|
_ValueList[index].ShowItem.Show(param);
|
|
}
|
|
}
|
|
|
|
public delegate void ShowItemFinish();
|
|
protected ShowItemFinish m_ShowItemFinish = null;
|
|
public void SetShowItemFinishCallFun(ShowItemFinish fun)
|
|
{
|
|
m_ShowItemFinish = fun;
|
|
}
|
|
|
|
public void SetLayoutPosotion(int index)
|
|
{
|
|
if(_LayoutGroup!=null)
|
|
{
|
|
_LayoutGroup.transform.localPosition = new Vector3(_LayoutGroup.transform.position.x, _LayoutGroup.cellSize.y * index, _LayoutGroup.transform.position.z);
|
|
}
|
|
}
|
|
|
|
public int GetItemCount()
|
|
{
|
|
return _ValueList.Count;
|
|
}
|
|
|
|
protected Hashtable _ExHash;
|
|
private bool _HasInit = false;
|
|
|
|
//[CSharpCallLua]
|
|
public virtual void InitContentItem(IEnumerable valueList, UIItemBase.ItemClick onClick = null, Hashtable exhash = null, UIItemBase.PanelClick onPanelClick = null)
|
|
{
|
|
_InitItemCountPrivate = _InitItemCount;
|
|
//CalculateRect(valueList);
|
|
_ValueList.Clear();
|
|
//ClearPrefab();
|
|
int i = 0;
|
|
if (valueList == null)
|
|
{
|
|
ClearPrefab();
|
|
return;
|
|
}
|
|
var enumerator = valueList.GetEnumerator();
|
|
enumerator.Reset();
|
|
while (enumerator.MoveNext())
|
|
{
|
|
var contentPos = new ContentPos();
|
|
contentPos.Obj = enumerator.Current;
|
|
_ValueList.Add(contentPos);
|
|
|
|
++i;
|
|
}
|
|
|
|
if (_InitItemCountPrivate <= 0)
|
|
{
|
|
_InitItemCountPrivate = 30;
|
|
}
|
|
_InitItemCountPrivate = Math.Min(_InitItemCountPrivate, _ValueList.Count);
|
|
|
|
_HasInit = false;
|
|
_OnClickItem = onClick;
|
|
_OnClickPanel = onPanelClick;
|
|
_ExHash = exhash;
|
|
if (isActiveAndEnabled)
|
|
{
|
|
|
|
StartInitContainer();
|
|
}
|
|
|
|
//_LayoutGroup.enabled = false;
|
|
|
|
}
|
|
|
|
// For lua
|
|
public void InitContentItemL2L(List<System.Object> valueList, UIItemBase.ItemClick onClick = null, Hashtable exhash = null, UIItemBase.PanelClick onPanelClick = null)
|
|
{
|
|
InitContentItem(valueList, onClick, exhash, onPanelClick);
|
|
}
|
|
|
|
public void StartInitContainer()
|
|
{
|
|
_HasInit = true;
|
|
if (_ValueList.Count > 0)
|
|
{
|
|
StartCoroutine(InitItems(_ExHash));
|
|
}
|
|
else
|
|
{
|
|
ClearPrefab();
|
|
}
|
|
}
|
|
|
|
public virtual void ShowItems()
|
|
{
|
|
|
|
}
|
|
|
|
public virtual void ShowItemsFinish()
|
|
{
|
|
if (m_ShowItemFinish != null)
|
|
m_ShowItemFinish.Invoke();
|
|
WindowSign wnd = gameObject.GetComponentInParent<WindowSign>();
|
|
if (wnd != null)
|
|
wnd.SetWndDirty();
|
|
}
|
|
|
|
private bool IsPosInView(ContentPos pos)
|
|
{
|
|
return (_ContainerObj.localPosition.x + pos.Pos.x >= -_LayoutGroup.cellSize.x * 0.5f
|
|
&& _ContainerObj.localPosition.x + pos.Pos.x <= _ViewPortWidth + _LayoutGroup.cellSize.x * 0.5f
|
|
&& -_ContainerObj.localPosition.y - pos.Pos.y >= -_LayoutGroup.cellSize.y * 0.5f
|
|
&& -_ContainerObj.localPosition.y - pos.Pos.y <= _ViewPortHeight + _LayoutGroup.cellSize.y * 0.5f);
|
|
}
|
|
|
|
private void InitItem(ContentPos contentItem, UIItemBase preItem, Hashtable exhash)
|
|
{
|
|
preItem.gameObject.SetActive(true);
|
|
//preItem.transform.localPosition = new Vector3(contentItem.Pos.x, contentItem.Pos.y, 0);
|
|
//if (preItem._InitInfo != contentItem.Obj)
|
|
{
|
|
Hashtable hash;
|
|
if (exhash == null)
|
|
{
|
|
hash = new Hashtable();
|
|
}
|
|
else
|
|
{
|
|
hash = new Hashtable(exhash);
|
|
}
|
|
|
|
hash.Add("InitObj", contentItem.Obj);
|
|
preItem.Show(hash);
|
|
preItem._InitInfo = contentItem.Obj;
|
|
|
|
preItem._ClickEvent = _OnClickItem;
|
|
preItem._PanelClickEvent = _OnClickPanel;
|
|
contentItem.ShowItem = preItem;
|
|
}
|
|
}
|
|
|
|
public virtual void RefreshItems()
|
|
{
|
|
foreach (var item in _ItemPrefabList)
|
|
{
|
|
item.Refresh();
|
|
}
|
|
}
|
|
|
|
public virtual void RefreshItems(Hashtable hash)
|
|
{
|
|
foreach (var item in _ItemPrefabList)
|
|
{
|
|
item.Refresh(hash);
|
|
}
|
|
}
|
|
|
|
public void PreLoadItem(int preLoadCount)
|
|
{
|
|
InitItems(null);
|
|
}
|
|
|
|
private void ClearPrefab()
|
|
{
|
|
foreach (var prefab in _ItemPrefabList)
|
|
{
|
|
//prefab.transform.localPosition = new Vector3(1000, 1000, 1);
|
|
prefab.Hide();
|
|
prefab._InitInfo = null;
|
|
}
|
|
}
|
|
|
|
private IEnumerator InitItems(Hashtable exhash)
|
|
{
|
|
//先初始化可见
|
|
//var itemPrefabList = _ContainerObj.GetComponentsInChildren<CommonItemBackPackItem>();
|
|
//_ItemPrefabList = new List<UIItemBase>(itemPrefabList);
|
|
//ClearPrefab();
|
|
if (_InitItemCountPrivate > _ItemPrefabList.Count)
|
|
{
|
|
for (int i = _ItemPrefabList.Count; i < _InitItemCountPrivate; ++i)
|
|
{
|
|
GameObject obj = GameObject.Instantiate<GameObject>(_ContainItemPre);
|
|
obj.transform.SetParent(_ContainerObj.transform);
|
|
obj.transform.localScale = Vector3.one;
|
|
obj.transform.localPosition = Vector3.zero;
|
|
|
|
obj.name = _ContainItemPre.name + _ItemPrefabList.Count;
|
|
var itemScript = obj.GetComponent<UIItemBase>();
|
|
//itemScript.Hide();
|
|
_ItemPrefabList.Add(itemScript);
|
|
//_EmpeyItemPrefab.Enqueue(itemScript);
|
|
}
|
|
}
|
|
|
|
|
|
for (int i = 0; i < _InitItemCountPrivate; ++i)
|
|
{
|
|
InitItem(_ValueList[i], _ItemPrefabList[i], exhash);
|
|
}
|
|
|
|
if (_ItemPrefabList.Count > _ValueList.Count)
|
|
{
|
|
for (int i = _ValueList.Count; i < _ItemPrefabList.Count; ++i)
|
|
{
|
|
_ItemPrefabList[i].Hide();
|
|
}
|
|
}
|
|
|
|
if (_InitItemCountPrivate >= _ValueList.Count)
|
|
{
|
|
ShowItemsFinish();
|
|
yield break;
|
|
}
|
|
|
|
yield return new WaitForFixedUpdate();
|
|
|
|
int nextNeedCount = _ValueList.Count - _InitItemCountPrivate;
|
|
if (nextNeedCount > 0)
|
|
{
|
|
int needCreateCount = nextNeedCount - (_ItemPrefabList.Count - _InitItemCountPrivate);
|
|
for (int i = 0; i < needCreateCount; ++i)
|
|
{
|
|
GameObject obj = GameObject.Instantiate<GameObject>(_ContainItemPre);
|
|
obj.transform.SetParent(_ContainerObj.transform);
|
|
obj.transform.localScale = Vector3.one;
|
|
obj.transform.localPosition = Vector3.zero;
|
|
var itemScript = obj.GetComponent<UIItemBase>();
|
|
//itemScript.Hide();
|
|
_ItemPrefabList.Add(itemScript);
|
|
//_EmpeyItemPrefab.Enqueue(itemScript);
|
|
}
|
|
|
|
for (int i = _InitItemCountPrivate; i < _ValueList.Count; ++i)
|
|
{
|
|
InitItem(_ValueList[i], _ItemPrefabList[i], exhash);
|
|
}
|
|
}
|
|
|
|
if (_ItemPrefabList.Count > _ValueList.Count)
|
|
{
|
|
for (int i = _ValueList.Count; i < _ItemPrefabList.Count; ++i)
|
|
{
|
|
_ItemPrefabList[i].Hide();
|
|
}
|
|
}
|
|
|
|
ShowItemsFinish();
|
|
}
|
|
|
|
public T GetContainItem<T>(int idx)
|
|
{
|
|
return _ItemPrefabList[idx].GetComponent<T>();
|
|
}
|
|
|
|
public void ForeachActiveItem<T>(Action<T> action)
|
|
{
|
|
for (int i = 0; i < _ItemPrefabList.Count; ++i)
|
|
{
|
|
if (_ItemPrefabList[i].gameObject.activeSelf)
|
|
{
|
|
var component = _ItemPrefabList[i].gameObject.GetComponent<T>();
|
|
if (component == null)
|
|
continue;
|
|
|
|
action(component);
|
|
}
|
|
}
|
|
}
|
|
|
|
public virtual void ForeachActiveBaseItemL2L(Action<LuaUIItemBase> action)
|
|
{
|
|
ForeachActiveItem<LuaUIItemBase>(action);
|
|
}
|
|
|
|
public Vector3 GetObjItemPos(object obj)
|
|
{
|
|
foreach (var item in _ItemPrefabList)
|
|
{
|
|
if (item._InitInfo == obj)
|
|
{
|
|
return item.transform.position;
|
|
}
|
|
}
|
|
return Vector3.zero;
|
|
}
|
|
}
|
|
|