基于UGUI制作ScrollRect
原生的插件往往都是面向大众需求,并不能完全的满足我们游戏的各种各样的需求,于是只能基于原有的逻辑增加自己的需求,在游戏中,滑动列表是最常见的,原生的滑动只是可以滑动,但是我们需要增加一个功能,整页整页的滑动。 我是.基于NGUI UIGrid 布局排列,基于NGUI UIWarpContent的ScrollRect内的item进行优化,
实现IBeginDragHandler, IEndDragHandler, IDragHandler接口
实现思路,通过滑动前,和滑动后,ScrollRect的偏移来确定用户是往哪个方向操作,然后计算每次翻页终点位置,在把ScrollRect移动到计算好的位置,
仔细观察 ScrollRect 提供了OnBeginDrag,OnDrag,OnEndDrag这三个虚函数,我需要自己实现这三个虚函数。
public class UIWarpContent : MonoBehaviour, IBeginDragHandler, IEndDragHandler, IDragHandler
public void OnBeginDrag(PointerEventData eventData)
{
scrollRect.OnBeginDrag(eventData);
}
public void OnEndDrag(PointerEventData eventData)
{
scrollRect.OnEndDrag(eventData);
}
public void OnDrag(PointerEventData eventData)
{
scrollRect.OnDrag(eventData);
}
我们是通过scrollRect的滑动来实现监听的,所以必须重写这些接口时,必须调用 scrollRect.OnDrag(eventData);
scrollRect.OnEndDrag(eventData);
scrollRect.OnBeginDrag(eventData);
不然我们是检测不到的。
最终完整代码
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;
using UnityEngine.EventSystems;
/**
* @des:滚动列表优化
* @注:
* 1.基于NGUI UIGrid 布局排列
* 2.基于NGUI UIWarpContent的ScrollRect内的item进行优化
* @date:2015-12-28
*/
//这个循环列表会计算content的大小,会计算item的位置。所有content的recttransform要清零,也不要带有任何布局的组件
[DisallowMultipleComponent]
public class UIWarpContent : MonoBehaviour, IBeginDragHandler, IEndDragHandler, IDragHandler
{
public delegate void OnInitializeItem(GameObject go, int dataIndex);
public OnInitializeItem onInitializeItem;
public string luaFunction;
public string m_onLuaItemInitFunction;
public enum Arrangement
{
Horizontal,
Vertical,
}
public Arrangement arrangement = Arrangement.Horizontal;
/// <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;
[HideInInspector]
public int m_nItemNumPerPage = 0; //每一个分页列表项的数量
[HideInInspector]
public int m_nPageNum = 0; //总共有多少页
private int m_nCurPageNum = 0; //当前页
bool m_IsNeedShowByPage = false; //是否需要以页为整数进行显示 (如果为true的话
float m_fNumOfItemWidthOrHeightChangePage = 1.0f; //当m_IsNeedShowByPage为true时 这个值设置滑动多少个列表项尺寸(水平垂直不同)时需要切换页
public UIScrollViewPageFlag m_ScrollViewPageFlag;
public ScrollRect scrollRect;
public RectTransform content;
public GameObject goItemPrefab;
[HideInInspector]
public int curScrollPerLineIndex = -1;
public float CurPos = 0;
#region DatePicker
public bool bDatePicker = false;
public int nStartIndex = 1;
public string dataPickerLuaFunc;
#endregion
/// <summary>
/// 滑动时的音效id
/// </summary>
public int ScrollAudioId = 0;
//想要个固定的contensize 为了子元素居中显示
public bool DontUpdateContentSize = false;
float m_fLastTime;
private bool m_bSetDatePickerPos;
float m_fLastPos;
private int m_dataCount;
private List<UIWarpContentItem> m_listItem = new List<UIWarpContentItem>();
private Queue<UIWarpContentItem> m_queueItem = new Queue<UIWarpContentItem>();
void Awake()
{
if (goItemPrefab != null) goItemPrefab.SetActive(false);
}
public void jumpTo(float fvalue)
{
Vector3 old = content.localPosition;
if (arrangement == Arrangement.Vertical)
{
scrollRect.verticalScrollbar.value = fvalue;
}
else
{
scrollRect.horizontalScrollbar.value = fvalue;
}
}
public void SetPos(float fvalue)
{
if (arrangement == Arrangement.Vertical)
{
scrollRect.verticalNormalizedPosition = Mathf.Clamp(fvalue, 0.0001f, 1 - 0.0001f);
}
else
{
scrollRect.horizontalNormalizedPosition = Mathf.Clamp(fvalue, 0.0001f, 1 - 0.0001f);
}
}
public float GetRectPos()
{
if (arrangement == Arrangement.Vertical)
{
return scrollRect.verticalNormalizedPosition;
}
else
{
return scrollRect.horizontalNormalizedPosition;
}
}
//改变之后会触发 onValueChanged
//fstep为多少个item的尺寸
public void PageUpOrDown(float fItemNum, bool bdown)
{
float fScoStep = GetStepLen(fItemNum);
float fCurPos = 0;
if (arrangement == Arrangement.Vertical)
{
fCurPos = scrollRect.verticalNormalizedPosition;
if (bdown)
{
scrollRect.verticalNormalizedPosition = Mathf.Clamp(fCurPos - fScoStep, 0, 1);
}
else
{
scrollRect.verticalNormalizedPosition = Mathf.Clamp(fCurPos + fScoStep, 0, 1);
}
}
else
{
fCurPos = scrollRect.horizontalNormalizedPosition;
if (bdown)
{
scrollRect.horizontalNormalizedPosition = Mathf.Clamp(fCurPos + fScoStep, 0, 1);
}
else
{
scrollRect.horizontalNormalizedPosition = Mathf.Clamp(fCurPos - fScoStep, 0, 1);
}
}
}
public float GetStepLen(float fItemNum)
{
float fScoStep;
if (arrangement == Arrangement.Vertical)
{
fScoStep = (fItemNum * (cellHeightSpace + cellHeight)) / (content.rect.height - scrollRect.GetComponent<RectTransform>().sizeDelta.y);
}
else
{
fScoStep = (fItemNum * (cellWidthSpace + cellWidth)) / (content.rect.width - scrollRect.GetComponent<RectTransform>().sizeDelta.x);
}
return fScoStep;
}
public void PageUpOrDown_Move(float fstep, bool bdown, float dura)
{
float fScoStep = GetStepLen(fstep);
float fCurPos = 0;
float ftarPos = 0;
if (arrangement == Arrangement.Vertical)
{
fCurPos = scrollRect.verticalNormalizedPosition;
if (bdown)
{
ftarPos = Mathf.Clamp(fCurPos - fScoStep, 0, 1);
}
else
{
ftarPos = Mathf.Clamp(fCurPos + fScoStep, 0, 1);
}
}
else
{
fCurPos = scrollRect.horizontalNormalizedPosition;
if (bdown)
{
ftarPos = Mathf.Clamp(fCurPos + fScoStep, 0, 1);
}
else
{
ftarPos = Mathf.Clamp(fCurPos - fScoStep, 0, 1);
}
}
Drag_Move(Time.time, dura, fCurPos, ftarPos, (int)arrangement);
}
public void Drag_Move(float start, float dura, float foripos, float ftarpos, int arrangement)
{
StartCoroutine(DragMove(start, dura, foripos, ftarpos, (Arrangement)arrangement));
}
IEnumerator DragMove(float start, float dura, float foripos, float ftarpos, Arrangement arrangement)
{
while (Time.time - start <= dura)
{
yield return null;
float fratio = Mathf.Clamp((Time.time - start) / dura, 0, 1);
float fpos = fratio * (ftarpos - foripos) + foripos;
if (arrangement == Arrangement.Vertical)
{
scrollRect.verticalNormalizedPosition = fpos;
}
else
{
scrollRect.horizontalNormalizedPosition = fpos;
}
}
}
public void Init(int dataCount)
{
for (int i = 0; i < m_listItem.Count; i++)
{
m_listItem[i].gameObject.SetActive(false);
m_listItem[i].gameObject.name = "itemunuse";
}
if (scrollRect == null || content == null || goItemPrefab == null)
{
Debugger.LogError("异常:请检测<" + gameObject.name + ">对象上UIWarpContent对应ScrollRect、Content、GoItemPrefab 是否存在值...." + scrollRect + " _" + content + "_" + goItemPrefab);
return;
}
if (dataCount <= 0)
{
ClearData();
return;
}
m_nCurPageNum = 0;
scrollRect.verticalNormalizedPosition = 1;
scrollRect.horizontalNormalizedPosition = 0;
scrollRect.onValueChanged.RemoveAllListeners();
scrollRect.onValueChanged.AddListener(onValueChanged);
var ite = m_listItem.GetEnumerator();
while (ite.MoveNext())
{
UIWarpContentItem item = ite.Current;
m_queueItem.Enqueue(item);
}
ite.Dispose();
m_listItem.Clear();
RectTransform sRect = scrollRect.GetComponent<RectTransform>();
if (arrangement == Arrangement.Vertical)
viewCount = Mathf.CeilToInt(sRect.rect.height / (cellHeight + cellHeightSpace)) + 1;
else
viewCount = Mathf.CeilToInt(sRect.rect.width / (cellWidth + cellWidthSpace)) + 1;
setDataCount(dataCount);
setUpdateRectItem(0);
//初始化 m_ScrollViewPageFlag
if (null != m_ScrollViewPageFlag)
{
m_ScrollViewPageFlag.InitPageFlag(m_nPageNum);
}
}
public void ClearData()
{
if (content.transform.childCount > 0)
{
List<UIWarpContentItem> listUIItem = ListPool<UIWarpContentItem>.Get();
content.transform.GetComponentsInChildren<UIWarpContentItem>(true, listUIItem);
for (int i = 0; i < listUIItem.Count; i++)
{
if (listUIItem[i])
{
Destroy(listUIItem[i].gameObject);
}
}
ListPool<UIWarpContentItem>.Release(listUIItem);
scrollRect.onValueChanged.RemoveAllListeners();
m_queueItem.Clear();
m_listItem.Clear();
if (arrangement == Arrangement.Vertical)
scrollRect.verticalNormalizedPosition = 1;
else
scrollRect.horizontalNormalizedPosition = 0;
}
}
private void setDataCount(int count)
{
m_nItemNumPerPage = (viewCount - 1) * maxPerLine;
m_nPageNum = Mathf.CeilToInt((float)count / m_nItemNumPerPage);
Debugger.LogError("m_nPageNum : " + m_nPageNum);
if (m_dataCount == count) return;
m_dataCount = count;
setUpdateContentSize();
}
public void onValueChanged(Vector2 vt2)
{
switch (arrangement)
{
case Arrangement.Vertical:
float y = vt2.y;
CurPos = Mathf.Clamp(y, 0, 1);
break;
case Arrangement.Horizontal:
float x = vt2.x;
CurPos = Mathf.Clamp(x, 0, 1);
break;
}
int _curScrollPerLineIndex = GetCurBeginIndex();
if (_curScrollPerLineIndex == curScrollPerLineIndex) return;
int lastStartIndex = nStartIndex;
setUpdateRectItem(_curScrollPerLineIndex);
if (ScrollAudioId > 0 && lastStartIndex != nStartIndex)
{
SoundManager.PlayAudio(ScrollAudioId);
}
}
private void CheckDatePickerPos()
{
if (m_bSetDatePickerPos) return;
int nTotalCount = m_dataCount - viewCount;
float fPerPosition = 1.0f / nTotalCount;
float fRemainPosition = 1 - scrollRect.verticalNormalizedPosition;
int nModifyPos = Mathf.FloorToInt(fRemainPosition / fPerPosition);
float fAmount = fRemainPosition / fPerPosition - nModifyPos;
if (fAmount >= 0.5)
{
++nModifyPos;
}
nStartIndex = nModifyPos + 1;
scrollRect.verticalNormalizedPosition = 1 - nModifyPos * fPerPosition;
m_bSetDatePickerPos = true;
LuaFunctionCall.Call(dataPickerLuaFunc, false);
}
public void Update()
{
if (!bDatePicker)
{
return;
}
if (Mathf.Abs(m_fLastPos - CurPos) <= 0.0001)
{
if (Time.time - m_fLastTime > 0.1)
CheckDatePickerPos();
}
else
{
m_bSetDatePickerPos = false;
m_fLastTime = Time.time;
}
m_fLastPos = CurPos;
}
/**
* @des:设置更新区域内item
* 功能:
* 1.隐藏区域之外对象
* 2.更新区域内数据
*/
private void setUpdateRectItem(int scrollPerLineIndex)
{
if (scrollPerLineIndex < 0) return;
curScrollPerLineIndex = scrollPerLineIndex;
int startDataIndex = curScrollPerLineIndex * maxPerLine;
int endDataIndex = (curScrollPerLineIndex + viewCount) * maxPerLine;
//移除
for (int i = m_listItem.Count - 1; i >= 0; i--)
{
UIWarpContentItem item = m_listItem[i];
int index = item.Index;
if (index < startDataIndex || index >= endDataIndex)
{
item.Index = -1;
m_listItem.Remove(item);
m_queueItem.Enqueue(item);
}
}
//显示
nStartIndex = startDataIndex + 1;
for (int dataIndex = startDataIndex; dataIndex < endDataIndex; dataIndex++)
{
if (dataIndex >= m_dataCount) continue;
if (isExistDataByDataIndex(dataIndex)) continue;
createItem(dataIndex);
}
}
/**
* @des:添加当前数据索引数据
*/
public void AddItem(int dataIndex)
{
if (dataIndex < 0 || dataIndex > m_dataCount)
{
return;
}
//检测是否需添加gameObject
bool isNeedAdd = false;
for (int i = m_listItem.Count - 1; i >= 0; i--)
{
UIWarpContentItem item = m_listItem[i];
if (item.Index >= (m_dataCount - 1))
{
isNeedAdd = true;
break;
}
}
setDataCount(m_dataCount + 1);
if (isNeedAdd)
{
for (int i = 0; i < m_listItem.Count; i++)
{
UIWarpContentItem item = m_listItem[i];
int oldIndex = item.Index;
if (oldIndex >= dataIndex)
{
item.Index = oldIndex + 1;
}
item = null;
}
setUpdateRectItem(GetCurBeginIndex());
}
else
{
//重新刷新数据
for (int i = 0; i < m_listItem.Count; i++)
{
UIWarpContentItem item = m_listItem[i];
int oldIndex = item.Index;
if (oldIndex >= dataIndex)
{
item.Index = oldIndex;
}
item = null;
}
}
}
/**
* @des:删除当前数据索引下数据
*/
public void DelItem(int dataIndex)
{
if (dataIndex < 0 || dataIndex >= m_dataCount)
{
return;
}
//删除item逻辑三种情况
//1.只更新数据,不销毁gameObject,也不移除gameobject
//2.更新数据,且移除gameObject,不销毁gameObject
//3.更新数据,销毁gameObject
bool isNeedDestroyGameObject = (m_listItem.Count >= m_dataCount);
setDataCount(m_dataCount - 1);
for (int i = m_listItem.Count - 1; i >= 0; i--)
{
UIWarpContentItem item = m_listItem[i];
int oldIndex = item.Index;
if (oldIndex == dataIndex)
{
m_listItem.Remove(item);
if (isNeedDestroyGameObject)
{
GameObject.Destroy(item.gameObject);
}
else
{
item.Index = -1;
m_queueItem.Enqueue(item);
}
}
if (oldIndex > dataIndex)
{
item.Index = oldIndex - 1;
}
}
setUpdateRectItem(GetCurBeginIndex());
}
/**
* @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);
y = -(index / maxPerLine) * (cellHeight + cellHeightSpace);
break;
}
return new Vector3(x, y, z);
}
/**
* @des:创建元素
* @param:dataIndex
*/
private void createItem(int dataIndex)
{
UIWarpContentItem item;
if (m_queueItem.Count > 0)
{
item = m_queueItem.Dequeue();
}
else
{
item = addChild(goItemPrefab, content).AddComponent<UIWarpContentItem>();
item.InitTable();
}
item.WarpContent = this;
item.Index = dataIndex;
m_listItem.Add(item);
}
/**
* @des:当前数据是否存在List中
*/
private bool isExistDataByDataIndex(int dataIndex)
{
if (m_listItem == null || m_listItem.Count <= 0)
{
return false;
}
for (int i = 0; i < m_listItem.Count; i++)
{
if (m_listItem[i].Index == dataIndex)
{
return true;
}
}
return false;
}
/**
* @des:根据Content偏移,计算当前开始显示所在数据列表中的行或列
*/
public int GetCurBeginIndex()
{
switch (arrangement)
{
case Arrangement.Horizontal: //水平方向
if (content.anchoredPosition.x >= 0)
{
return 0;
}
return Mathf.FloorToInt(Mathf.Abs(content.anchoredPosition.x) / (cellWidth + cellWidthSpace));
case Arrangement.Vertical://垂着方向
if (content.anchoredPosition.y <= 0)
{
return 0;
}
return Mathf.FloorToInt(Mathf.Abs(content.anchoredPosition.y) / (cellHeight + cellHeightSpace));
}
return 0;
}
/**
* @des:更新Content SizeDelta
*/
private void setUpdateContentSize()
{
if (DontUpdateContentSize) return;
int lineCount = Mathf.CeilToInt((float)m_dataCount / maxPerLine);
switch (arrangement)
{
case Arrangement.Horizontal:
content.sizeDelta = new Vector2(cellWidth * lineCount + cellWidthSpace * lineCount, content.sizeDelta.y);
break;
case Arrangement.Vertical:
content.sizeDelta = new Vector2(content.sizeDelta.x, cellHeight * lineCount + cellHeightSpace * lineCount);
break;
}
}
/**
* @des:实例化预设对象 、添加实例化对象到指定的子对象下
*/
private GameObject addChild(GameObject goPrefab, Transform parent)
{
if (goPrefab == null || parent == null)
{
Debugger.LogError("异常。UIWarpContent.cs addChild(goPrefab = null || parent = null)");
return null;
}
GameObject goChild = GameObject.Instantiate(goPrefab) as GameObject;
goChild.layer = parent.gameObject.layer;
goChild.transform.SetParent(parent, false);
return goChild;
}
public void RefreshItem()
{
for (int i = 0; i < m_listItem.Count; i++)
{
if (m_listItem[i] != null)
{
m_listItem[i].InitializeItem();
}
}
}
void OnDestroy()
{
scrollRect = null;
content = null;
goItemPrefab = null;
onInitializeItem = null;
m_listItem.Clear();
m_queueItem.Clear();
m_listItem = null;
m_queueItem = null;
}
//index 为1开始
//isShowBegin是否显示在开始位置
public void jumpToIndex(int index, bool isShowBegin = false)
{
Vector3 contentVec3 = content.transform.localPosition;
RectTransform sRect = scrollRect.GetComponent<RectTransform>();
if (arrangement == Arrangement.Vertical)
{
if (content.rect.height <= sRect.rect.height) return;
float jump = (Mathf.CeilToInt((float)index / maxPerLine) - 1) * (cellHeight + cellHeightSpace);
if (!isShowBegin)
jump -= sRect.rect.height;
if (jump >= 0)
{
float maxHeight = content.rect.height - sRect.rect.height;
if (jump > maxHeight)
jump = maxHeight;
content.transform.localPosition = new Vector3(contentVec3.x, jump, contentVec3.z);
}
}
else
{
if (content.rect.width <= sRect.rect.width) return;
float jump = (Mathf.CeilToInt((float)index / maxPerLine) - 1) * (cellWidth + cellWidthSpace);
if (!isShowBegin)
jump -= sRect.rect.width;
if (jump >= 0)
{
float maxWidth = content.rect.width - sRect.rect.width;
if (jump > maxWidth)
jump = maxWidth;
content.transform.localPosition = new Vector3(-jump, contentVec3.y, contentVec3.z);
}
}
}
//index为1开始
public void jumpToPageIndex(int index)
{
if (index <= 0 || index > m_nPageNum)
return;
jumpToIndex(m_nItemNumPerPage * (index - 1) + 1, true);
}
//是否需要以页为单位进行显示 (如果为true的话滑动 m_fNumOfItemWidthOrHeightChangePage个item尺寸切换页)
public void SetIsNeedShowByPage(bool state)
{
m_IsNeedShowByPage = state;
if (state)
{
scrollRect.inertia = false;
if (DontUpdateContentSize) return;
int lineCount = Mathf.CeilToInt((float)m_dataCount / maxPerLine);
switch (arrangement)
{
case Arrangement.Horizontal:
content.sizeDelta = new Vector2(content.sizeDelta.x, scrollRect.GetComponent<RectTransform>().sizeDelta.y);
break;
case Arrangement.Vertical:
content.sizeDelta = new Vector2(scrollRect.GetComponent<RectTransform>().sizeDelta.x, content.sizeDelta.y);
break;
}
}
}
public void SetNumOfItemWidthOrHeightChangePage(float fNum)
{
m_fNumOfItemWidthOrHeightChangePage = fNum;
}
#region 拖拽相关 龙建
//拖拽前
private Vector3 nBeginDragPos = Vector3.zero;
private Vector3 nEndDragPos = Vector3.zero;
public float nMoverSpeed = 20f;
public void OnBeginDrag(PointerEventData eventData)
{
scrollRect.OnBeginDrag(eventData);
if (!m_IsNeedShowByPage)
{
return;
}
nBeginDragPos = content.localPosition;
}
public void OnEndDrag(PointerEventData eventData)
{
scrollRect.OnEndDrag(eventData);
if (!m_IsNeedShowByPage)
{
return;
}
nEndDragPos = content.localPosition;
if (arrangement == Arrangement.Vertical)
{
ArrangementVertical();
}
else if (arrangement == Arrangement.Horizontal)
{
ArrangementHorizontal();
}
}
public void OnDrag(PointerEventData eventData)
{
scrollRect.OnDrag(eventData);
}
private void ArrangementVertical()
{
if (nBeginDragPos.y > nEndDragPos.y)
{
if (m_nCurPageNum == 0)
{
return;
}
//往下滑动
m_nCurPageNum--;
float scrollRectPos = m_nCurPageNum * m_nItemNumPerPage * cellHeight;
Vector3 endPos = new Vector3(content.localPosition.x, scrollRectPos);
StartCoroutine(DragPageMove(endPos));
}
else
{
//往上滑动
if (m_nCurPageNum >= m_nPageNum - 1)
{
return;
}
m_nCurPageNum++;
//最后一页需要判断是否整数
float scrollRectPos = 0f;
if ((m_nCurPageNum + 1) * m_nItemNumPerPage >= m_dataCount)
{
float deviation = ((m_nCurPageNum + 1) * m_nItemNumPerPage - m_dataCount) * cellHeight;
scrollRectPos = m_nCurPageNum * m_nItemNumPerPage * cellHeight - deviation;
}
else
{
scrollRectPos = m_nCurPageNum * m_nItemNumPerPage * cellHeight;
}
Vector3 endPos = new Vector3(content.localPosition.x, scrollRectPos);
StartCoroutine(DragPageMove(endPos));
}
}
private void ArrangementHorizontal()
{
if (nBeginDragPos.x < nEndDragPos.x)
{
if (m_nCurPageNum == 0)
{
return;
}
//往右边滑动
m_nCurPageNum--;
float scrollRectPos = m_nCurPageNum * m_nItemNumPerPage * cellWidth;
Vector3 endPos = new Vector3(-scrollRectPos, content.localPosition.y);
StartCoroutine(DragPageMove(endPos));
}
else
{
//往左边滑动
if (m_nCurPageNum >= m_nPageNum - 1)
{
return;
}
m_nCurPageNum++;
//最后一页需要判断是否整数
float scrollRectPos = 0f;
if ((m_nCurPageNum + 1) * m_nItemNumPerPage >= m_dataCount)
{
float deviation = ((m_nCurPageNum + 1) * m_nItemNumPerPage - m_dataCount) * cellWidth;
scrollRectPos = m_nCurPageNum * m_nItemNumPerPage * cellHeight - deviation;
}
else
{
scrollRectPos = m_nCurPageNum * m_nItemNumPerPage * cellWidth;
}
Vector3 endPos = new Vector3(-scrollRectPos, content.localPosition.y);
StartCoroutine(DragPageMove(endPos));
}
}
IEnumerator DragPageMove(Vector3 endPos)
{
//刷新小提示分页
if (null != m_ScrollViewPageFlag)
{
bool isLastPage = (m_nCurPageNum + 1) >= m_nPageNum ? true : false;
m_ScrollViewPageFlag.UpdatePage(m_nCurPageNum + 1, isLastPage);
}
if (arrangement == Arrangement.Vertical)
{
//距离
while (Mathf.Abs(content.transform.localPosition.y - endPos.y) >= cellHeight / 4)
{
yield return null;
content.localPosition = Vector3.MoveTowards(content.localPosition, endPos, nMoverSpeed);
if (content.localPosition.y <= 0)
{
break;
}
}
}
else if (arrangement == Arrangement.Horizontal)
{
//距离
while (Mathf.Abs(content.transform.localPosition.x - endPos.x) >= cellWidth / 4)
{
yield return null;
content.localPosition = Vector3.MoveTowards(content.localPosition, endPos, nMoverSpeed);
if (content.localPosition.x >= 0)
{
break;
}
}
}
content.localPosition = endPos;
}
#endregion
}
滚动分页 展示当前第几分页
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;
using UnityEngine.EventSystems;
/**
* @des:滚动分页 展示当前第几分页
* @author:龙建
* @date:2020-03-05
*/
public class UIScrollViewPageFlag : MonoBehaviour
{
//public UIWarpContent m_uiWarpContent;
public GameObject m_flagObg;
public GameObject m_Grid;
private const int m_minPageNum = 3;//最少的分页
private List<PageFlagItem> m_listPageFlage = new List<PageFlagItem>();
private void Awake()
{
if (m_flagObg == null)
{
m_flagObg = this.transform.Find("flagItem").gameObject;
}
if (m_flagObg == null)
{
Debug.LogError("flagItem is bull");
}
if (m_Grid == null)
{
m_Grid = this.transform.Find("FlagParent/Grid").gameObject;
}
if (m_Grid == null)
{
Debug.LogError("Grid is bull");
}
}
public void InitPageFlag(int pageNum)
{
m_listPageFlage.Clear();
for (int i = 0; i < m_minPageNum; i++)
{
GameObject go = GameObject.Instantiate(m_flagObg);
go.transform.parent = m_Grid.transform;
go.SetActive(true);
PageFlagItem pageFlagItem = go.AddComponent<PageFlagItem>();
m_listPageFlage.Add(pageFlagItem);
}
bool isLastPage = pageNum > 1 ? false : true;
UpdatePage(1, isLastPage);
}
public void UpdatePage(int curPage, bool isLastPage)
{
int count = m_listPageFlage.Count;
int indexShow = curPage % m_minPageNum;
for (int i = 0; i < count; i++)
{
m_listPageFlage[i].m_image.gameObject.SetActive(false);
m_listPageFlage[i].m_text.gameObject.SetActive(false);
}
if (indexShow != 0)
{
m_listPageFlage[indexShow - 1].m_text.text = curPage.ToString();
m_listPageFlage[indexShow - 1].m_text.gameObject.SetActive(true);
}
else
{
m_listPageFlage[count - 1].m_text.text = curPage.ToString();
m_listPageFlage[count - 1].m_text.gameObject.SetActive(true);
}
//当前页是最后一页
if(isLastPage && indexShow != 0)
{
for (int i = indexShow; i < count; i++)
{
m_listPageFlage[i].m_image.gameObject.SetActive(true);
}
}
}
}
public class PageFlagItem : MonoBehaviour
{
public Image m_image;
public Text m_text;
private void Awake()
{
m_image = this.transform.Find("Image").GetComponent<Image>();
m_text = this.transform.Find("Text").GetComponent<Text>();
}
}