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的回调设置为GoToNextPageGoToPrevPage即可。

 

posted @ 2020-07-06 20:50  0kk470  阅读(397)  评论(0编辑  收藏  举报