chicken_dy/Assets/Scripts/UI/CustomControl/PageView.cs

242 lines
5.7 KiB
C#
Raw Normal View History

2022-02-12 12:01:05 +00:00
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using System.Collections.Generic;
using UnityEngine.EventSystems;
using System;
2022-02-13 09:36:12 +00:00
public abstract class PageView : MonoBehaviour, IBeginDragHandler, IEndDragHandler
2022-02-12 12:01:05 +00:00
{
2022-02-14 09:14:06 +00:00
public Action<int> OnPageChanged;
protected Action OnScrollPage;
protected Action OnReachEdge;
2022-02-13 09:36:12 +00:00
public int CountPerPage;
2022-02-12 12:01:05 +00:00
public float SlideSpeed = 4; //滑动速度
public float sensitivity = 0.3f;
2022-02-13 10:18:17 +00:00
[SerializeField] PageSpot mSpotView;
2022-02-13 09:36:12 +00:00
[SerializeField] Transform mCtnPage;
[SerializeField] GameObject mTplPage;
[SerializeField] GameObject mTplCell;
2022-02-12 12:01:05 +00:00
ScrollRect rect; //滑动组件
private float targethorizontal = 0; //滑动的起始坐标
private bool isDrag = false; //是否拖拽结束
2022-02-13 10:18:17 +00:00
List<float> posList = new List<float>();//求出每页的临界角页索引从0开始
2022-02-12 12:01:05 +00:00
private int currentPageIndex = -1;
private bool stopMove = true;
private float startTime;
private float startDragHorizontal;
2022-02-13 09:36:12 +00:00
protected List<GameObject> mCellList;
protected List<Transform> mPageList;
2022-02-12 12:01:05 +00:00
2022-02-13 09:36:12 +00:00
#region page scroll
2022-02-12 12:01:05 +00:00
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)
2022-02-13 10:18:17 +00:00
{
2022-02-12 12:01:05 +00:00
stopMove = true;
2022-02-13 10:18:17 +00:00
NotifyPageChange();
}
2022-02-12 12:01:05 +00:00
}
}
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;
2022-02-14 09:14:06 +00:00
OnReachEdge?.Invoke();
2022-02-12 12:01:05 +00:00
}
else
{
rect.horizontalNormalizedPosition = posList[index];
2022-02-13 10:18:17 +00:00
NotifyPageChange();
2022-02-12 12:01:05 +00:00
}
}
else
{
2022-02-14 09:14:06 +00:00
OnReachEdge?.Invoke();
2022-02-13 10:18:17 +00:00
//Debug.LogError("页码不存在");
2022-02-12 12:01:05 +00:00
}
}
2022-02-13 10:18:17 +00:00
public void LastPage()
{
PageTo(currentPageIndex--);
}
public void NextPage()
{
PageTo(currentPageIndex++);
}
2022-02-12 12:01:05 +00:00
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);
}
2022-02-13 10:18:17 +00:00
private void NotifyPageChange()
{
OnPageChanged?.Invoke(currentPageIndex);
if (mSpotView != null)
{
mSpotView.SetPageIndex(currentPageIndex);
}
}
2022-02-13 09:36:12 +00:00
#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();
2022-02-13 10:18:17 +00:00
if (mSpotView != null)
{
mSpotView.Init(mPageCount);
}
2022-02-13 09:36:12 +00:00
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
2022-02-12 12:01:05 +00:00
}