255 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			C#
		
	
	
	
			
		
		
	
	
			255 lines
		
	
	
		
			6.0 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>();
 | ||
|         AwakeInit();
 | ||
|     }
 | ||
| 
 | ||
|     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)
 | ||
|                 {
 | ||
|                     OnScrollPage?.Invoke();
 | ||
|                 }
 | ||
|             }
 | ||
| 
 | ||
|             if (pWithScroll)
 | ||
|             {
 | ||
|                 targethorizontal = posList[currentPageIndex]; //设置当前坐标,更新函数进行插值 
 | ||
|                 isDrag = false;
 | ||
|                 startTime = 0;
 | ||
|                 stopMove = false;
 | ||
|             }
 | ||
|             else
 | ||
|             {
 | ||
|                 rect.horizontalNormalizedPosition = posList[index];
 | ||
| 
 | ||
|                 NotifyPageChange();
 | ||
|             }
 | ||
|         }
 | ||
|         else
 | ||
|         {
 | ||
|             //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);
 | ||
|         float tTempPosX = posX;
 | ||
|         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);
 | ||
| 
 | ||
|         if (tTempPosX > 1 || tTempPosX < 0)
 | ||
|         {
 | ||
|             OnReachEdge?.Invoke();
 | ||
|         }
 | ||
|     }
 | ||
| 
 | ||
|     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 AwakeInit();
 | ||
|     protected abstract void BeforeLoad();
 | ||
| 
 | ||
|     protected abstract void ConfigCell(GameObject pCellGob, int pIndex);
 | ||
| 
 | ||
|     public void LoadData()
 | ||
|     {
 | ||
|         BeforeLoad();
 | ||
| 
 | ||
|         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
 | ||
| } |