Files
Main/Assets/GameAssets/Resources/GameUI/Common/UILoopScrollView/UILoopScrollViewBase.cs
2025-01-25 04:38:09 +08:00

364 lines
13 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//**********************************************//
//作者:#何健#
//日期:#2016.10.09#
//简述:#ScrollView优化使用一定数量子项实现大量数据循环加载#
//*********************************************//
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Text;
namespace Thousandto.Plugins.Common
{
/// <summary>
/// 类BackPackItem说明
/// </summary>
[RequireComponent(typeof(UIGrid))]
public class UILoopScrollViewBase : MonoCacheBase
{
#region Members
/// <summary>
/// 存储物件列表
/// </summary>
private List<GameObject> m_itemList = new List<GameObject>();
/// <summary>
/// 起始下标
/// </summary>
private int _startIndex = 1;
/// <summary>
/// 最大长度
/// </summary>
private int _maxCount;
/// <summary>
/// 父ScrollView
/// </summary>
public UIScrollView _scrollView;
/// <summary>
/// grid
/// </summary>
public UIGrid _grid;
/// <summary>
/// templateItem
/// </summary>
public GameObject _templateItem;
/// <summary>
/// 物件刷新代理事件
/// </summary>
/// <param name="go"></param>
public delegate void OnItemChange(Transform obj, string name, bool isClear);
private OnItemChange m_pItemChangeCallBack;
private Vector2 _scrollViewPos = new Vector2(0, 0);
private Vector3 lastPos;
private bool _isRecodePos = false;
#endregion
#region
/// <summary>
/// 设置代理
/// </summary>
/// <param name="_onItemChange"></param>
public void SetDelegate(OnItemChange _onItemChange)
{
m_pItemChangeCallBack = _onItemChange;
}
/// <summary>
/// 物件刷新代理事件
/// </summary>
/// <param name="go"></param>
private void OnItemChangeMsg(Transform obj,string name, bool isClear)
{
if (m_pItemChangeCallBack != null)
{
m_pItemChangeCallBack(obj, name, isClear);
}
}
#endregion
/// <summary>
/// 初始化表
/// </summary>
public void Init(int maxCount, GameObject templateItem = null, int waitCount = 1, bool isResetScrool = true)
{
_isRecodePos = false;
_maxCount = maxCount;
if (isResetScrool)
{
// 如果传入有控件则以传入的为模板如果没有则查找grid下面第一个子控件
_grid = transform.GetComponent<UIGrid>();
_scrollView = transform.parent.GetComponent<UIScrollView>();
_grid.gameObject.SetActive(true);
var _num = _maxCount % _grid.maxPerLine;
if (_num != 0)
{
_maxCount = _maxCount + _grid.maxPerLine - _num;
}
if (templateItem)
{
_templateItem = templateItem;
}
else
{
_templateItem = _grid.transform.GetChild(0).gameObject;
}
try
{
StartCoroutine(Respositon(waitCount));
}
finally
{
}
}
else
{
//当前显示出来的第一个格子在grid数据中的index
var childCount = _grid.transform.childCount;
int index = Mathf.FloorToInt((_maxCount - childCount) / _grid.maxPerLine);
for (int i = index * _grid.maxPerLine; i < childCount + index * _grid.maxPerLine; i++)
{
if (i >= _maxCount)
return;
FillItem(i - index * _grid.maxPerLine + _startIndex, i + _startIndex, i == childCount + index * _grid.maxPerLine - 1);
}
}
}
private IEnumerator Respositon(int waitCount = 0)
{
InitGird();
_grid.Reposition();
yield return waitCount;
_scrollView.ResetPosition();
_isRecodePos = true;
}
private void InitGird()
{
m_itemList.Clear();
// 将现有的子项添加到容器
for (int i = 0; i < _grid.transform.childCount; i++)
{
GameObject go = _grid.transform.GetChild(i).gameObject;
//go.SetActive(false);
m_itemList.Add(go);
}
int fillCount = 0; //当前scrollView被填满的格子数
int lastIndex = 0; //上次显示出来的第一个格子在grid数据中的index
var _indexDis = 0f;
UIPanel panel = _scrollView.GetComponent<UIPanel>();
if (_scrollView.movement == UIScrollView.Movement.Vertical)
{
fillCount = Mathf.CeilToInt(panel.height / _grid.cellHeight);
fillCount = fillCount * _grid.maxPerLine;
_indexDis = _grid.cellHeight;
}
else if (_scrollView.movement == UIScrollView.Movement.Horizontal)
{
fillCount = Mathf.CeilToInt(panel.width / _grid.cellWidth);
_indexDis = _grid.cellWidth;
}
//if (_maxCount < fillCount + _grid.maxPerLine)
// _maxCount = fillCount + _grid.maxPerLine;
int childCount = _maxCount;
// 如果item数量大于填满显示面板的数量做优化
if (childCount > fillCount + _grid.maxPerLine)
{
childCount = fillCount + _grid.maxPerLine;
// 拖拽刷新面板
panel.onClipMove = (uiPanel) => {
Vector3 delata = lastPos - panel.transform.localPosition;
float distance = System.Math.Abs(delata.y) > 0.5 ? delata.y : delata.x;
// 满的时候向上滑不管它
if ((distance > 0 && _scrollView.movement == UIScrollView.Movement.Vertical) || (distance < 0 && _scrollView.movement == UIScrollView.Movement.Horizontal))
return;
if (distance < 0)
distance = -distance;
//当前显示出来的第一个格子在grid数据中的index
int index = Mathf.FloorToInt(distance / _indexDis);
// 拖拽不满一个单元格
if (index == lastIndex) return;
// 拉到底了
if (index + childCount > _maxCount) {
for (int i = 1; i <= _grid.transform.childCount; i++)
{
if (i >= _maxCount)
return;
var _newKey = _maxCount >= _grid.transform.childCount ? _maxCount - _grid.transform.childCount + i : i;
FillItem(i, _newKey, i == _grid.transform.childCount);
}
return;
}
lastIndex = index;
// 重刷
if ((index - 1) * _grid.maxPerLine + childCount < _maxCount)
{
for (int i = index * _grid.maxPerLine; i < childCount + index * _grid.maxPerLine; i++)
{
if (i >= _maxCount)
return;
FillItem(i - index * _grid.maxPerLine + _startIndex, i + _startIndex, i == childCount + index * _grid.maxPerLine - 1);
}
}
};
}
_scrollView.onStoppedMoving = OnDragFinished;
// 添加能填满UI数量的子项
var allCount = fillCount + _grid.maxPerLine;
for (int i = 0; i < allCount; i++)
{
bool isClear = false;
if (i == 0)
{
isClear = true;
}
if (i >= _maxCount)
{
break;
}
GameObject go = null;
if (i < m_itemList.Count)
{
go = m_itemList[i];
}
else
{
go = NGUITools.AddChild(_grid.gameObject, _templateItem);
m_itemList.Add(go);
}
go.SetActive(true);
FillItem(i + _startIndex, i + _startIndex, isClear);
//if (m_itemList.Count > i)
//{
// FillItem(i + _startIndex, i + _startIndex, isClear);
// continue;
//}
//GameObject go = NGUITools.AddChild(_grid.gameObject, _templateItem);
//go.SetActive(true);
//m_itemList.Add(go);
//FillItem(i + _startIndex, i + _startIndex, isClear);
}
for (int i = allCount; i < m_itemList.Count; i++)
{
m_itemList[i].SetActive(false);
}
lastPos = panel.transform.localPosition;
}
public void OnDragFinished()
{
if (_scrollView.movement == UIScrollView.Movement.Vertical)
{
int indexY = (int)_scrollViewPos.y;
if (indexY + 10 > (int)_scrollView.transform.localPosition.y && indexY - 10 < (int)_scrollView.transform.localPosition.y)
{
for (int i = 0; i < _grid.transform.childCount; i++)
{
if (i >= _maxCount)
return;
FillItem(i + _startIndex, i + _startIndex, i == _grid.transform.childCount - 1);
}
}
}
else if(_scrollView.movement == UIScrollView.Movement.Horizontal)
{
int indexY = (int)_scrollViewPos.x;
if (indexY + 10 > (int)_scrollView.transform.localPosition.x && indexY - 10 < (int)_scrollView.transform.localPosition.x)
{
for (int i = 0; i < _grid.transform.childCount; i++)
{
if (i >= _maxCount)
return;
FillItem(i + _startIndex, i + _startIndex, i == _grid.transform.childCount - 1);
}
}
}
}
// 修改子项位置
public void FillItem(int oldIndex, int index, bool isClear)
{
//Debug.Log("-----oldIndex=" + oldIndex + ",index = " + index + ", itemListCount=" + m_itemList.Count);
int iListIndex = oldIndex - _startIndex;
if (m_itemList.Count <= iListIndex)
return;
string oldKey = m_itemList[iListIndex].name;
string newKey = index.ToString();
m_itemList[iListIndex].name = newKey;
if (_scrollView.movement == UIScrollView.Movement.Horizontal)// 如果是水平滑动,则只有一排
{
m_itemList[iListIndex].transform.localPosition = new Vector3(_grid.cellWidth * (index - 1), 0, 0);
}
else if (_scrollView.movement == UIScrollView.Movement.Vertical) // 纵向滑动时有可能有多列
{
int count = index / _grid.maxPerLine;
int countLess = index % _grid.maxPerLine;
if(countLess == 0)
{
countLess = _grid.maxPerLine - _startIndex;
if(_startIndex != 0)
{
count -= 1;
}
}
else
{
countLess -= _startIndex;
}
m_itemList[iListIndex].transform.localPosition = new Vector3(countLess * _grid.cellWidth, -_grid.cellHeight * count, 0);
m_itemList[iListIndex].gameObject.SetActive(true);
}
OnItemChangeMsg(m_itemList[iListIndex].transform, newKey, isClear);
}
// 修改最大格子数
public void OnSetMaxIndex(int max)
{
_maxCount = max;
if(_grid != null)
{
var _num = _maxCount % _grid.maxPerLine;
if (_num != 0)
{
_maxCount = _maxCount - _grid.maxPerLine + _num;
}
}
}
// 修改最大格子数
public int OnGetMaxIndex()
{
return _maxCount;
}
//重置lastpos
public void ResetPos()
{
lastPos = _scrollView.GetComponent<UIPanel>().transform.localPosition;
}
private void Update()
{
if (_isRecodePos)
{
_scrollViewPos = _scrollView.transform.localPosition;
ResetPos();
_isRecodePos = false;
}
}
}
}