242 lines
5.7 KiB
C#
242 lines
5.7 KiB
C#
using UnityEngine;
|
||
using System.Collections;
|
||
using UnityEngine.UI;
|
||
using System.Collections.Generic;
|
||
using UnityEngine.EventSystems;
|
||
using System;
|
||
|
||
public abstract class PageView : MonoBehaviour, IBeginDragHandler, IEndDragHandler
|
||
{
|
||
public Action<int> OnPageChanged;
|
||
|
||
protected Action OnScrollPage;
|
||
protected Action OnReachEdge;
|
||
|
||
public int CountPerPage;
|
||
|
||
public float SlideSpeed = 4; //滑动速度
|
||
public float sensitivity = 0.3f;
|
||
|
||
[SerializeField] PageSpot mSpotView;
|
||
[SerializeField] Transform mCtnPage;
|
||
[SerializeField] GameObject mTplPage;
|
||
[SerializeField] GameObject mTplCell;
|
||
|
||
ScrollRect rect; //滑动组件
|
||
private float targethorizontal = 0; //滑动的起始坐标
|
||
private bool isDrag = false; //是否拖拽结束
|
||
List<float> posList = new List<float>();//求出每页的临界角,页索引从0开始
|
||
private int currentPageIndex = -1;
|
||
|
||
private bool stopMove = true;
|
||
private float startTime;
|
||
|
||
private float startDragHorizontal;
|
||
|
||
protected List<GameObject> mCellList;
|
||
protected List<Transform> mPageList;
|
||
|
||
#region page scroll
|
||
void Awake()
|
||
{
|
||
rect = transform.GetComponent<ScrollRect>();
|
||
}
|
||
|
||
void Update()
|
||
{
|
||
if (!isDrag && !stopMove)
|
||
{
|
||
startTime += Time.deltaTime;
|
||
float t = startTime * SlideSpeed;
|
||
rect.horizontalNormalizedPosition = Mathf.Lerp(rect.horizontalNormalizedPosition, targethorizontal, t);
|
||
if (t >= 1)
|
||
{
|
||
stopMove = true;
|
||
NotifyPageChange();
|
||
}
|
||
}
|
||
}
|
||
|
||
public void PageTo(int index, bool pWithScroll = true)
|
||
{
|
||
if (index >= 0 && index < posList.Count)
|
||
{
|
||
if (currentPageIndex != index)
|
||
{
|
||
currentPageIndex = index;
|
||
}
|
||
|
||
if (pWithScroll)
|
||
{
|
||
targethorizontal = posList[currentPageIndex]; //设置当前坐标,更新函数进行插值
|
||
isDrag = false;
|
||
startTime = 0;
|
||
stopMove = false;
|
||
|
||
OnReachEdge?.Invoke();
|
||
}
|
||
else
|
||
{
|
||
rect.horizontalNormalizedPosition = posList[index];
|
||
|
||
NotifyPageChange();
|
||
}
|
||
}
|
||
else
|
||
{
|
||
OnReachEdge?.Invoke();
|
||
//Debug.LogError("页码不存在");
|
||
}
|
||
}
|
||
|
||
public void LastPage()
|
||
{
|
||
PageTo(currentPageIndex--);
|
||
}
|
||
|
||
public void NextPage()
|
||
{
|
||
PageTo(currentPageIndex++);
|
||
}
|
||
|
||
public void OnBeginDrag(PointerEventData eventData)
|
||
{
|
||
isDrag = true;
|
||
startDragHorizontal = rect.horizontalNormalizedPosition;
|
||
}
|
||
|
||
public void OnEndDrag(PointerEventData eventData)
|
||
{
|
||
float posX = rect.horizontalNormalizedPosition;
|
||
posX += ((posX - startDragHorizontal) * sensitivity);
|
||
posX = posX < 1 ? posX : 1;
|
||
posX = posX > 0 ? posX : 0;
|
||
int index = 0;
|
||
float offset = Mathf.Abs(posList[index] - posX);
|
||
for (int i = 1; i < posList.Count; i++)
|
||
{
|
||
float temp = Mathf.Abs(posList[i] - posX);
|
||
if (temp < offset)
|
||
{
|
||
index = i;
|
||
offset = temp;
|
||
}
|
||
}
|
||
PageTo(index);
|
||
}
|
||
|
||
private void NotifyPageChange()
|
||
{
|
||
OnPageChanged?.Invoke(currentPageIndex);
|
||
if (mSpotView != null)
|
||
{
|
||
mSpotView.SetPageIndex(currentPageIndex);
|
||
}
|
||
}
|
||
#endregion
|
||
|
||
#region config cell
|
||
|
||
public abstract int Count
|
||
{
|
||
get;
|
||
}
|
||
|
||
public int PageCount => mPageCount;
|
||
|
||
private int mPageCount;
|
||
|
||
protected abstract void ConfigCell(GameObject pCellGob, int pIndex);
|
||
|
||
public void LoadData()
|
||
{
|
||
mPageCount = Count / CountPerPage + ((Count % CountPerPage) > 0 ? 1 : 0);
|
||
|
||
int tSplitCount = Mathf.Max(1, mPageCount);
|
||
float tDelta = tSplitCount > 1 ? (1f / (tSplitCount - 1)) : 1;
|
||
|
||
for (int i = 0; i < tSplitCount; i++)
|
||
{
|
||
posList.Add(tDelta * i);
|
||
}
|
||
|
||
for (int i = 0; i < Count; i++)
|
||
{
|
||
GameObject tCell = GetCell(i);
|
||
ConfigCell(tCell, i);
|
||
}
|
||
|
||
HideUnused();
|
||
|
||
if (mSpotView != null)
|
||
{
|
||
mSpotView.Init(mPageCount);
|
||
}
|
||
|
||
PageTo(0, false);
|
||
}
|
||
|
||
private GameObject GetCell(int pCellIndex)
|
||
{
|
||
if (mCellList == null)
|
||
{
|
||
mCellList = new List<GameObject>();
|
||
}
|
||
|
||
GameObject tCell = null;
|
||
if (pCellIndex < mCellList.Count)
|
||
{
|
||
tCell = mCellList[pCellIndex];
|
||
}
|
||
else
|
||
{
|
||
tCell = Instantiate(mTplCell, GetPage(pCellIndex));
|
||
tCell.transform.localScale = Vector3.one;
|
||
mCellList.Add(tCell);
|
||
}
|
||
|
||
tCell.SetActive(true);
|
||
|
||
return tCell;
|
||
}
|
||
|
||
private Transform GetPage(int pCellIndex)
|
||
{
|
||
if (mPageList == null)
|
||
{
|
||
mPageList = new List<Transform>();
|
||
}
|
||
|
||
int tPageIndex = pCellIndex / CountPerPage;
|
||
|
||
Transform tPage = null;
|
||
if (tPageIndex < mPageList.Count)
|
||
{
|
||
tPage = mPageList[tPageIndex];
|
||
}
|
||
else
|
||
{
|
||
tPage = Instantiate(mTplPage, mCtnPage).transform;
|
||
mPageList.Add(tPage);
|
||
}
|
||
|
||
tPage.gameObject.SetActive(true);
|
||
|
||
return tPage;
|
||
}
|
||
|
||
private void HideUnused()
|
||
{
|
||
for (int i = Count; i < mCellList.Count; i++)
|
||
{
|
||
mCellList[i].SetActive(false);
|
||
}
|
||
|
||
for (int i = PageCount; i < mPageList.Count; i++)
|
||
{
|
||
mPageList[i].gameObject.SetActive(false);
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
} |