NGUI带翻页的滑动列表拓展
前言
策划需要一个既可以滑动又能够翻页的列表显示。
实现
using System; using UnityEngine; /* 带翻页效果的滑动列表 by kk47 */ [RequireComponent(typeof(UIScrollView))] [RequireComponent(typeof(SpringPanel))] public class PageScrollView : MonoBehaviour { public Vector2 ChildSize = new Vector2(100, 100); public bool IsMoving { get; private set; } = false; public int CurrentPage { get; private set; } = 0; private Vector3 m_InitPosition; [SerializeField] private int m_NumPerPage = 1; public int NumPerPage { get { return m_NumPerPage; } set { m_NumPerPage = value; UpdateCurrentPage(); } } [SerializeField] private int m_ChildCount = 0; public int ChildCount { get { return m_ChildCount; } set { m_ChildCount = value; UpdateCurrentPage(); } } public int MaxPage { get { var result = ChildCount / NumPerPage; result += ChildCount % NumPerPage == 0 ? 0 : 1; return result; } } private UIScrollView m_ScrollView; public UIScrollView ScrollView { get { if (m_ScrollView == null) m_ScrollView = GetComponent<UIScrollView>(); return m_ScrollView; } } private SpringPanel m_Spring; public SpringPanel SpringPanel { get { if (m_Spring == null) m_Spring = GetComponent<SpringPanel>(); return m_Spring; } } private void Awake() { ScrollView.onMomentumMove += OnMove; ScrollView.onStoppedMoving += OnStop; SpringPanel.enabled = false; } void Start() { m_InitPosition = transform.localPosition; } private void OnDestroy() { ScrollView.onMomentumMove -= OnMove; ScrollView.onStoppedMoving -= OnStop; } private void OnSpringFinish() { UpdateCurrentPage(); } private void OnMove() { IsMoving = true; UpdateCurrentPage(); } private void OnStop() { IsMoving = false; UpdateCurrentPage(); } [ContextMenu("NextPage")] public void GoToNextPage() { if (IsMoving || SpringPanel.enabled) return; var NextPage = Math.Min(CurrentPage + 1, MaxPage); DoMove(NextPage); } [ContextMenu("PrevPage")] public void GoToPrevPage() { if (IsMoving || SpringPanel.enabled) return; var PrevPage = Math.Max(CurrentPage - 1, 0); DoMove(PrevPage); } public void GoToSpecificPage(int page) { page = Math.Min(Math.Max(0, page), MaxPage - 1); SpringPanel.enabled = false; DoMove(page); } private async void DoMove(int page) { bool isHorizontal = ScrollView.movement == UIScrollView.Movement.Horizontal; var MoveChildCount = Math.Max(0, Math.Min(NumPerPage * page, ChildCount - NumPerPage)); var MoveContentSize = ChildSize * MoveChildCount; var offset = isHorizontal ? new Vector3(MoveContentSize.x, 0, 0) : new Vector3(0, MoveContentSize.y, 0); var pos = m_InitPosition - offset; SpringPanel.target = pos; SpringPanel.onFinished = OnSpringFinish; await System.Threading.Tasks.Task.Delay(100); SpringPanel.enabled = true; } private void UpdateCurrentPage() { var offset = m_InitPosition - transform.localPosition; var distance = ScrollView.movement == UIScrollView.Movement.Horizontal ? offset.x : offset.y; var itemSize = ScrollView.movement == UIScrollView.Movement.Horizontal ? ChildSize.x : ChildSize.y; var pageSize = itemSize * NumPerPage; var newPage = Mathf.FloorToInt(distance / pageSize); newPage = Math.Min(Math.Max(0, newPage), MaxPage - 1); CurrentPage = newPage; } }
效果
使用
设置好ChildSize、NumPerPage、ChildCount ,挂载在UIScrollView的GameObject上,将相关Button的回调设置为GoToNextPage和GoToPrevPage即可。