UGUI ScrollRect 翻页模块

基于UGUI制作ScrollRect

原生的插件往往都是面向大众需求,并不能完全的满足我们游戏的各种各样的需求,于是只能基于原有的逻辑增加自己的需求,在游戏中,滑动列表是最常见的,原生的滑动只是可以滑动,但是我们需要增加一个功能,整页整页的滑动。 我是.基于NGUI UIGrid 布局排列,基于NGUI UIWarpContent的ScrollRect内的item进行优化,

实现IBeginDragHandler, IEndDragHandler, IDragHandler接口

实现思路,通过滑动前,和滑动后,ScrollRect的偏移来确定用户是往哪个方向操作,然后计算每次翻页终点位置,在把ScrollRect移动到计算好的位置,
仔细观察 ScrollRect 提供了OnBeginDrag,OnDrag,OnEndDrag这三个虚函数,我需要自己实现这三个虚函数。

public class UIWarpContent : MonoBehaviour, IBeginDragHandler, IEndDragHandler, IDragHandler


    public void OnBeginDrag(PointerEventData eventData)
    {
        scrollRect.OnBeginDrag(eventData);
    }

    public void OnEndDrag(PointerEventData eventData)
    {
        scrollRect.OnEndDrag(eventData);

    }

    public void OnDrag(PointerEventData eventData)
    {
        scrollRect.OnDrag(eventData);
    }

我们是通过scrollRect的滑动来实现监听的,所以必须重写这些接口时,必须调用 scrollRect.OnDrag(eventData);
scrollRect.OnEndDrag(eventData);
scrollRect.OnBeginDrag(eventData);
不然我们是检测不到的。

最终完整代码

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;
using UnityEngine.EventSystems;

/**
 * @des:滚动列表优化 
 * @注:
 * 1.基于NGUI UIGrid 布局排列
 * 2.基于NGUI UIWarpContent的ScrollRect内的item进行优化
 * @date:2015-12-28
*/
//这个循环列表会计算content的大小,会计算item的位置。所有content的recttransform要清零,也不要带有任何布局的组件
[DisallowMultipleComponent]
public class UIWarpContent : MonoBehaviour, IBeginDragHandler, IEndDragHandler, IDragHandler
{
    public delegate void OnInitializeItem(GameObject go, int dataIndex);

    public OnInitializeItem onInitializeItem;

    public string luaFunction;
    public string m_onLuaItemInitFunction;

    public enum Arrangement
    {
        Horizontal,
        Vertical,
    }

    public Arrangement arrangement = Arrangement.Horizontal;

    /// <summary>
    /// Maximum children per line.
    /// If the arrangement is horizontal, this denotes the number of columns.
    /// If the arrangement is vertical, this stands for the number of rows.
    /// </summary>
    [Range(1, 50)]
    public int maxPerLine = 1;

    /// <summary>
    /// The width of each of the cells.
    /// </summary>

    public float cellWidth = 200f;

    /// <summary>
    /// The height of each of the cells.
    /// </summary>

    public float cellHeight = 200f;

    /// <summary>
    /// The Width Space of each of the cells.
    /// </summary>
    [Range(0, 200)]
    public float cellWidthSpace = 0f;

    /// <summary>
    /// The Height Space of each of the cells.
    /// </summary>
    [Range(0, 200)]
    public float cellHeightSpace = 0f;


    [Range(0, 30)]
    public int viewCount = 5;

    [HideInInspector]
    public int m_nItemNumPerPage = 0;  //每一个分页列表项的数量
    [HideInInspector]
    public int m_nPageNum = 0;         //总共有多少页
    private int m_nCurPageNum = 0;      //当前页

    bool m_IsNeedShowByPage = false;   //是否需要以页为整数进行显示  (如果为true的话 
    float m_fNumOfItemWidthOrHeightChangePage = 1.0f;   //当m_IsNeedShowByPage为true时 这个值设置滑动多少个列表项尺寸(水平垂直不同)时需要切换页

    public UIScrollViewPageFlag m_ScrollViewPageFlag;

    public ScrollRect scrollRect;

    public RectTransform content;

    public GameObject goItemPrefab;

    [HideInInspector]
    public int curScrollPerLineIndex = -1;

    public float CurPos = 0;

    #region DatePicker
    public bool bDatePicker = false;
    public int nStartIndex = 1;
    public string dataPickerLuaFunc;
    #endregion

    /// <summary>
    /// 滑动时的音效id
    /// </summary>
    public int ScrollAudioId = 0;

    //想要个固定的contensize 为了子元素居中显示
    public bool DontUpdateContentSize = false;

    float m_fLastTime;
    private bool m_bSetDatePickerPos;
    float m_fLastPos;
    private int m_dataCount;
    private List<UIWarpContentItem> m_listItem = new List<UIWarpContentItem>();
    private Queue<UIWarpContentItem> m_queueItem = new Queue<UIWarpContentItem>();

    void Awake()
    {
        if (goItemPrefab != null) goItemPrefab.SetActive(false);
    }

    public void jumpTo(float fvalue)
    {
        Vector3 old = content.localPosition;
        if (arrangement == Arrangement.Vertical)
        {
            scrollRect.verticalScrollbar.value = fvalue;
        }
        else
        {
            scrollRect.horizontalScrollbar.value = fvalue;
        }
    }

    public void SetPos(float fvalue)
    {
        if (arrangement == Arrangement.Vertical)
        {
            scrollRect.verticalNormalizedPosition = Mathf.Clamp(fvalue, 0.0001f, 1 - 0.0001f);
        }
        else
        {
            scrollRect.horizontalNormalizedPosition = Mathf.Clamp(fvalue, 0.0001f, 1 - 0.0001f);
        }

    }

    public float GetRectPos()
    {
        if (arrangement == Arrangement.Vertical)
        {
            return scrollRect.verticalNormalizedPosition;
        }
        else
        {
            return scrollRect.horizontalNormalizedPosition;
        }
    }

    //改变之后会触发 onValueChanged
    //fstep为多少个item的尺寸
    public void PageUpOrDown(float fItemNum, bool bdown)
    {
        float fScoStep = GetStepLen(fItemNum);

        float fCurPos = 0;
        if (arrangement == Arrangement.Vertical)
        {
            fCurPos = scrollRect.verticalNormalizedPosition;
            if (bdown)
            {
                scrollRect.verticalNormalizedPosition = Mathf.Clamp(fCurPos - fScoStep, 0, 1);
            }
            else
            {
                scrollRect.verticalNormalizedPosition = Mathf.Clamp(fCurPos + fScoStep, 0, 1);
            }
        }
        else
        {
            fCurPos = scrollRect.horizontalNormalizedPosition;
            if (bdown)
            {
                scrollRect.horizontalNormalizedPosition = Mathf.Clamp(fCurPos + fScoStep, 0, 1);
            }
            else
            {
                scrollRect.horizontalNormalizedPosition = Mathf.Clamp(fCurPos - fScoStep, 0, 1);
            }
        }
    }

    public float GetStepLen(float fItemNum)
    {
        float fScoStep;
        if (arrangement == Arrangement.Vertical)
        {
            fScoStep = (fItemNum * (cellHeightSpace + cellHeight)) / (content.rect.height - scrollRect.GetComponent<RectTransform>().sizeDelta.y);
        }
        else
        {
            fScoStep = (fItemNum * (cellWidthSpace + cellWidth)) / (content.rect.width - scrollRect.GetComponent<RectTransform>().sizeDelta.x);
        }
        return fScoStep;
    }

    public void PageUpOrDown_Move(float fstep, bool bdown, float dura)
    {
        float fScoStep = GetStepLen(fstep);
        float fCurPos = 0;
        float ftarPos = 0;
        if (arrangement == Arrangement.Vertical)
        {
            fCurPos = scrollRect.verticalNormalizedPosition;
            if (bdown)
            {
                ftarPos = Mathf.Clamp(fCurPos - fScoStep, 0, 1);
            }
            else
            {
                ftarPos = Mathf.Clamp(fCurPos + fScoStep, 0, 1);
            }
        }
        else
        {
            fCurPos = scrollRect.horizontalNormalizedPosition;
            if (bdown)
            {
                ftarPos = Mathf.Clamp(fCurPos + fScoStep, 0, 1);
            }
            else
            {
                ftarPos = Mathf.Clamp(fCurPos - fScoStep, 0, 1);
            }
        }
        Drag_Move(Time.time, dura, fCurPos, ftarPos, (int)arrangement);
    }

    public void Drag_Move(float start, float dura, float foripos, float ftarpos, int arrangement)
    {
        StartCoroutine(DragMove(start, dura, foripos, ftarpos, (Arrangement)arrangement));
    }

    IEnumerator DragMove(float start, float dura, float foripos, float ftarpos, Arrangement arrangement)
    {
        while (Time.time - start <= dura)
        {
            yield return null;
            float fratio = Mathf.Clamp((Time.time - start) / dura, 0, 1);
            float fpos = fratio * (ftarpos - foripos) + foripos;
            if (arrangement == Arrangement.Vertical)
            {
                scrollRect.verticalNormalizedPosition = fpos;
            }
            else
            {
                scrollRect.horizontalNormalizedPosition = fpos;
            }
        }
    }

    public void Init(int dataCount)
    {
        for (int i = 0; i < m_listItem.Count; i++)
        {
            m_listItem[i].gameObject.SetActive(false);
            m_listItem[i].gameObject.name = "itemunuse";
        }

        if (scrollRect == null || content == null || goItemPrefab == null)
        {
            Debugger.LogError("异常:请检测<" + gameObject.name + ">对象上UIWarpContent对应ScrollRect、Content、GoItemPrefab 是否存在值...." + scrollRect + " _" + content + "_" + goItemPrefab);
            return;
        }

        if (dataCount <= 0)
        {
            ClearData();
            return;
        }

        m_nCurPageNum = 0;

        scrollRect.verticalNormalizedPosition = 1;
        scrollRect.horizontalNormalizedPosition = 0;

        scrollRect.onValueChanged.RemoveAllListeners();
        scrollRect.onValueChanged.AddListener(onValueChanged);


        var ite = m_listItem.GetEnumerator();
        while (ite.MoveNext())
        {
            UIWarpContentItem item = ite.Current;
            m_queueItem.Enqueue(item);
        }
        ite.Dispose();

        m_listItem.Clear();

        RectTransform sRect = scrollRect.GetComponent<RectTransform>();
        if (arrangement == Arrangement.Vertical)
            viewCount = Mathf.CeilToInt(sRect.rect.height / (cellHeight + cellHeightSpace)) + 1;
        else
            viewCount = Mathf.CeilToInt(sRect.rect.width / (cellWidth + cellWidthSpace)) + 1;

        setDataCount(dataCount);
        setUpdateRectItem(0);
        //初始化 m_ScrollViewPageFlag
        if (null != m_ScrollViewPageFlag)
        {
            m_ScrollViewPageFlag.InitPageFlag(m_nPageNum);
        }
    }

    public void ClearData()
    {
        if (content.transform.childCount > 0)
        {
            List<UIWarpContentItem> listUIItem = ListPool<UIWarpContentItem>.Get();
            content.transform.GetComponentsInChildren<UIWarpContentItem>(true, listUIItem);

            for (int i = 0; i < listUIItem.Count; i++)
            {
                if (listUIItem[i])
                {
                    Destroy(listUIItem[i].gameObject);
                }
            }
            ListPool<UIWarpContentItem>.Release(listUIItem);

            scrollRect.onValueChanged.RemoveAllListeners();
            m_queueItem.Clear();
            m_listItem.Clear();

            if (arrangement == Arrangement.Vertical)
                scrollRect.verticalNormalizedPosition = 1;
            else
                scrollRect.horizontalNormalizedPosition = 0;
        }
    }

    private void setDataCount(int count)
    {
        m_nItemNumPerPage = (viewCount - 1) * maxPerLine;
        m_nPageNum = Mathf.CeilToInt((float)count / m_nItemNumPerPage);
        Debugger.LogError("m_nPageNum : " + m_nPageNum);
        if (m_dataCount == count) return;
        m_dataCount = count;

        setUpdateContentSize();
    }

    public void onValueChanged(Vector2 vt2)
    {
        switch (arrangement)
        {
            case Arrangement.Vertical:
                float y = vt2.y;
                CurPos = Mathf.Clamp(y, 0, 1);
                break;
            case Arrangement.Horizontal:
                float x = vt2.x;
                CurPos = Mathf.Clamp(x, 0, 1);
                break;
        }

        int _curScrollPerLineIndex = GetCurBeginIndex();
        if (_curScrollPerLineIndex == curScrollPerLineIndex) return;

        int lastStartIndex = nStartIndex;
        setUpdateRectItem(_curScrollPerLineIndex);

        if (ScrollAudioId > 0 && lastStartIndex != nStartIndex)
        {
            SoundManager.PlayAudio(ScrollAudioId);
        }
    }

    private void CheckDatePickerPos()
    {
        if (m_bSetDatePickerPos) return;

        int nTotalCount = m_dataCount - viewCount;
        float fPerPosition = 1.0f / nTotalCount;
        float fRemainPosition = 1 - scrollRect.verticalNormalizedPosition;
        int nModifyPos = Mathf.FloorToInt(fRemainPosition / fPerPosition);
        float fAmount = fRemainPosition / fPerPosition - nModifyPos;
        if (fAmount >= 0.5)
        {
            ++nModifyPos;
        }
        nStartIndex = nModifyPos + 1;
        scrollRect.verticalNormalizedPosition = 1 - nModifyPos * fPerPosition;
        m_bSetDatePickerPos = true;
        LuaFunctionCall.Call(dataPickerLuaFunc, false);
    }

    public void Update()
    {
        if (!bDatePicker)
        {
            return;
        }
        if (Mathf.Abs(m_fLastPos - CurPos) <= 0.0001)
        {
            if (Time.time - m_fLastTime > 0.1)
                CheckDatePickerPos();
        }
        else
        {
            m_bSetDatePickerPos = false;
            m_fLastTime = Time.time;
        }
        m_fLastPos = CurPos;
    }

    /**
     * @des:设置更新区域内item
     * 功能:
     * 1.隐藏区域之外对象
     * 2.更新区域内数据
     */
    private void setUpdateRectItem(int scrollPerLineIndex)
    {
        if (scrollPerLineIndex < 0) return;

        curScrollPerLineIndex = scrollPerLineIndex;
        int startDataIndex = curScrollPerLineIndex * maxPerLine;
        int endDataIndex = (curScrollPerLineIndex + viewCount) * maxPerLine;

        //移除
        for (int i = m_listItem.Count - 1; i >= 0; i--)
        {
            UIWarpContentItem item = m_listItem[i];
            int index = item.Index;
            if (index < startDataIndex || index >= endDataIndex)
            {
                item.Index = -1;
                m_listItem.Remove(item);
                m_queueItem.Enqueue(item);
            }
        }

        //显示
        nStartIndex = startDataIndex + 1;
        for (int dataIndex = startDataIndex; dataIndex < endDataIndex; dataIndex++)
        {
            if (dataIndex >= m_dataCount) continue;

            if (isExistDataByDataIndex(dataIndex)) continue;

            createItem(dataIndex);
        }
    }

    /**
     * @des:添加当前数据索引数据
     */
    public void AddItem(int dataIndex)
    {
        if (dataIndex < 0 || dataIndex > m_dataCount)
        {
            return;
        }
        //检测是否需添加gameObject
        bool isNeedAdd = false;
        for (int i = m_listItem.Count - 1; i >= 0; i--)
        {
            UIWarpContentItem item = m_listItem[i];
            if (item.Index >= (m_dataCount - 1))
            {
                isNeedAdd = true;
                break;
            }
        }
        setDataCount(m_dataCount + 1);

        if (isNeedAdd)
        {
            for (int i = 0; i < m_listItem.Count; i++)
            {
                UIWarpContentItem item = m_listItem[i];
                int oldIndex = item.Index;
                if (oldIndex >= dataIndex)
                {
                    item.Index = oldIndex + 1;
                }
                item = null;
            }
            setUpdateRectItem(GetCurBeginIndex());
        }
        else
        {
            //重新刷新数据
            for (int i = 0; i < m_listItem.Count; i++)
            {
                UIWarpContentItem item = m_listItem[i];
                int oldIndex = item.Index;
                if (oldIndex >= dataIndex)
                {
                    item.Index = oldIndex;
                }
                item = null;
            }
        }

    }

    /**
     * @des:删除当前数据索引下数据
     */
    public void DelItem(int dataIndex)
    {
        if (dataIndex < 0 || dataIndex >= m_dataCount)
        {
            return;
        }
        //删除item逻辑三种情况
        //1.只更新数据,不销毁gameObject,也不移除gameobject
        //2.更新数据,且移除gameObject,不销毁gameObject
        //3.更新数据,销毁gameObject

        bool isNeedDestroyGameObject = (m_listItem.Count >= m_dataCount);
        setDataCount(m_dataCount - 1);

        for (int i = m_listItem.Count - 1; i >= 0; i--)
        {
            UIWarpContentItem item = m_listItem[i];
            int oldIndex = item.Index;
            if (oldIndex == dataIndex)
            {
                m_listItem.Remove(item);
                if (isNeedDestroyGameObject)
                {
                    GameObject.Destroy(item.gameObject);
                }
                else
                {
                    item.Index = -1;
                    m_queueItem.Enqueue(item);
                }
            }
            if (oldIndex > dataIndex)
            {
                item.Index = oldIndex - 1;
            }
        }
        setUpdateRectItem(GetCurBeginIndex());
    }

    /**
     * @des:获取当前index下对应Content下的本地坐标
     * @param:index
     * @内部使用
    */
    public Vector3 getLocalPositionByIndex(int index)
    {
        float x = 0f;
        float y = 0f;
        float z = 0f;
        switch (arrangement)
        {
            case Arrangement.Horizontal: //水平方向
                x = (index / maxPerLine) * (cellWidth + cellWidthSpace);
                y = -(index % maxPerLine) * (cellHeight + cellHeightSpace);
                break;
            case Arrangement.Vertical://垂着方向
                x = (index % maxPerLine) * (cellWidth + cellWidthSpace);
                y = -(index / maxPerLine) * (cellHeight + cellHeightSpace);
                break;
        }
        return new Vector3(x, y, z);
    }

    /**
     * @des:创建元素
     * @param:dataIndex
     */
    private void createItem(int dataIndex)
    {
        UIWarpContentItem item;
        if (m_queueItem.Count > 0)
        {
            item = m_queueItem.Dequeue();
        }
        else
        {
            item = addChild(goItemPrefab, content).AddComponent<UIWarpContentItem>();
            item.InitTable();   
        }

        item.WarpContent = this;
        item.Index = dataIndex;
        m_listItem.Add(item);
    }

    /**
     * @des:当前数据是否存在List中
     */
    private bool isExistDataByDataIndex(int dataIndex)
    {
        if (m_listItem == null || m_listItem.Count <= 0)
        {
            return false;
        }
        for (int i = 0; i < m_listItem.Count; i++)
        {
            if (m_listItem[i].Index == dataIndex)
            {
                return true;
            }
        }
        return false;
    }

    /**
     * @des:根据Content偏移,计算当前开始显示所在数据列表中的行或列
     */
    public int GetCurBeginIndex()
    {
        switch (arrangement)
        {
            case Arrangement.Horizontal: //水平方向
                if (content.anchoredPosition.x >= 0)
                {
                    return 0;
                }
                return Mathf.FloorToInt(Mathf.Abs(content.anchoredPosition.x) / (cellWidth + cellWidthSpace));
            case Arrangement.Vertical://垂着方向
                if (content.anchoredPosition.y <= 0)
                {
                    return 0;
                }
                return Mathf.FloorToInt(Mathf.Abs(content.anchoredPosition.y) / (cellHeight + cellHeightSpace));
        }
        return 0;
    }

    /**
     * @des:更新Content SizeDelta
     */
    private void setUpdateContentSize()
    {
        if (DontUpdateContentSize) return;

        int lineCount = Mathf.CeilToInt((float)m_dataCount / maxPerLine);
        switch (arrangement)
        {
            case Arrangement.Horizontal:
                content.sizeDelta = new Vector2(cellWidth * lineCount + cellWidthSpace * lineCount, content.sizeDelta.y);
                break;
            case Arrangement.Vertical:
                content.sizeDelta = new Vector2(content.sizeDelta.x, cellHeight * lineCount + cellHeightSpace * lineCount);
                break;
        }
    }

    /**
     * @des:实例化预设对象 、添加实例化对象到指定的子对象下
     */
    private GameObject addChild(GameObject goPrefab, Transform parent)
    {
        if (goPrefab == null || parent == null)
        {
            Debugger.LogError("异常。UIWarpContent.cs addChild(goPrefab = null  || parent = null)");
            return null;
        }

        GameObject goChild = GameObject.Instantiate(goPrefab) as GameObject;
        goChild.layer = parent.gameObject.layer;
        goChild.transform.SetParent(parent, false);

        return goChild;
    }

    public void RefreshItem()
    {
        for (int i = 0; i < m_listItem.Count; i++)
        {
            if (m_listItem[i] != null)
            {
                m_listItem[i].InitializeItem();
            }
        }
    }

    void OnDestroy()
    {
        scrollRect = null;
        content = null;
        goItemPrefab = null;
        onInitializeItem = null;

        m_listItem.Clear();
        m_queueItem.Clear();

        m_listItem = null;
        m_queueItem = null;
    }


    //index 为1开始
    //isShowBegin是否显示在开始位置
    public void jumpToIndex(int index, bool isShowBegin = false)
    {
        Vector3 contentVec3 = content.transform.localPosition;
        RectTransform sRect = scrollRect.GetComponent<RectTransform>();
        if (arrangement == Arrangement.Vertical)
        {
            if (content.rect.height <= sRect.rect.height) return;

            float jump = (Mathf.CeilToInt((float)index / maxPerLine) - 1) * (cellHeight + cellHeightSpace);
            if (!isShowBegin)
                jump -= sRect.rect.height;

            if (jump >= 0)
            {
                float maxHeight = content.rect.height - sRect.rect.height;
                if (jump > maxHeight)
                    jump = maxHeight;
                content.transform.localPosition = new Vector3(contentVec3.x, jump, contentVec3.z);
            }
        }
        else
        {
            if (content.rect.width <= sRect.rect.width) return;

            float jump = (Mathf.CeilToInt((float)index / maxPerLine) - 1) * (cellWidth + cellWidthSpace);
            if (!isShowBegin)
                jump -= sRect.rect.width;

            if (jump >= 0)
            {
                float maxWidth = content.rect.width - sRect.rect.width;
                if (jump > maxWidth)
                    jump = maxWidth;
                content.transform.localPosition = new Vector3(-jump, contentVec3.y, contentVec3.z);
            }
        }
    }

    //index为1开始
    public void jumpToPageIndex(int index)
    {
        if (index <= 0 || index > m_nPageNum)
            return;
        jumpToIndex(m_nItemNumPerPage * (index - 1) + 1, true);
    }

    //是否需要以页为单位进行显示  (如果为true的话滑动  m_fNumOfItemWidthOrHeightChangePage个item尺寸切换页)
    public void SetIsNeedShowByPage(bool state)
    {
        m_IsNeedShowByPage = state;
        if (state)
        {
            scrollRect.inertia = false;
            if (DontUpdateContentSize) return;

            int lineCount = Mathf.CeilToInt((float)m_dataCount / maxPerLine);
            switch (arrangement)
            {
                case Arrangement.Horizontal:
                    content.sizeDelta = new Vector2(content.sizeDelta.x, scrollRect.GetComponent<RectTransform>().sizeDelta.y);
                    break;
                case Arrangement.Vertical:
                    content.sizeDelta = new Vector2(scrollRect.GetComponent<RectTransform>().sizeDelta.x, content.sizeDelta.y);
                    break;
            }
        }
    }

    public void SetNumOfItemWidthOrHeightChangePage(float fNum)
    {
        m_fNumOfItemWidthOrHeightChangePage = fNum;
    }

    #region 拖拽相关 龙建 
    //拖拽前
    private Vector3 nBeginDragPos = Vector3.zero;
    private Vector3 nEndDragPos = Vector3.zero;
    public float nMoverSpeed = 20f;

    public void OnBeginDrag(PointerEventData eventData)
    {
        scrollRect.OnBeginDrag(eventData);
        if (!m_IsNeedShowByPage)
        {
            return;
        }

        nBeginDragPos = content.localPosition;
    }

    public void OnEndDrag(PointerEventData eventData)
    {
        scrollRect.OnEndDrag(eventData);
        if (!m_IsNeedShowByPage)
        {
            return;
        }

        nEndDragPos = content.localPosition;
        if (arrangement == Arrangement.Vertical)
        {
            ArrangementVertical();
        }
        else if (arrangement == Arrangement.Horizontal)
        {
            ArrangementHorizontal();
        }
    }

    public void OnDrag(PointerEventData eventData)
    {
        scrollRect.OnDrag(eventData);
    }


    private void ArrangementVertical()
    {
        if (nBeginDragPos.y > nEndDragPos.y)
        {
            if (m_nCurPageNum == 0)
            {
                return;
            }
            //往下滑动
            m_nCurPageNum--;
            float scrollRectPos = m_nCurPageNum * m_nItemNumPerPage * cellHeight;
            Vector3 endPos = new Vector3(content.localPosition.x, scrollRectPos);
            StartCoroutine(DragPageMove(endPos));
        }
        else
        {
            //往上滑动
            if (m_nCurPageNum >= m_nPageNum - 1)
            {
                return;
            }
            m_nCurPageNum++;
            //最后一页需要判断是否整数

            float scrollRectPos = 0f;
            if ((m_nCurPageNum + 1) * m_nItemNumPerPage >= m_dataCount)
            {
                float deviation = ((m_nCurPageNum + 1) * m_nItemNumPerPage - m_dataCount) * cellHeight;
                scrollRectPos = m_nCurPageNum * m_nItemNumPerPage * cellHeight - deviation;
            }
            else
            {
                scrollRectPos = m_nCurPageNum * m_nItemNumPerPage * cellHeight;
            }

            Vector3 endPos = new Vector3(content.localPosition.x, scrollRectPos);
            StartCoroutine(DragPageMove(endPos));
        }
    }

    private void ArrangementHorizontal()
    {
        if (nBeginDragPos.x < nEndDragPos.x)
        {
            if (m_nCurPageNum == 0)
            {
                return;
            }
            //往右边滑动
            m_nCurPageNum--;
            float scrollRectPos = m_nCurPageNum * m_nItemNumPerPage * cellWidth;
            Vector3 endPos = new Vector3(-scrollRectPos, content.localPosition.y);
            StartCoroutine(DragPageMove(endPos));
        }
        else
        {
            //往左边滑动
            if (m_nCurPageNum >= m_nPageNum - 1)
            {
                return;
            }
            m_nCurPageNum++;
            //最后一页需要判断是否整数

            float scrollRectPos = 0f;
            if ((m_nCurPageNum + 1) * m_nItemNumPerPage >= m_dataCount)
            {
                float deviation = ((m_nCurPageNum + 1) * m_nItemNumPerPage - m_dataCount) * cellWidth;
                scrollRectPos = m_nCurPageNum * m_nItemNumPerPage * cellHeight - deviation;
            }
            else
            {
                scrollRectPos = m_nCurPageNum * m_nItemNumPerPage * cellWidth;
            }

            Vector3 endPos = new Vector3(-scrollRectPos, content.localPosition.y);
            StartCoroutine(DragPageMove(endPos));
        }
    }


    IEnumerator DragPageMove(Vector3 endPos)
    {
        //刷新小提示分页
        if (null != m_ScrollViewPageFlag)
        {
            bool isLastPage = (m_nCurPageNum + 1) >= m_nPageNum ? true : false;
            m_ScrollViewPageFlag.UpdatePage(m_nCurPageNum + 1, isLastPage);
        }


        if (arrangement == Arrangement.Vertical)
        {
            //距离
            while (Mathf.Abs(content.transform.localPosition.y - endPos.y) >= cellHeight / 4)
            {
                yield return null;
                content.localPosition = Vector3.MoveTowards(content.localPosition, endPos, nMoverSpeed);
                if (content.localPosition.y <= 0)
                {
                    break;
                }
            }
        }
        else if (arrangement == Arrangement.Horizontal)
        {
            //距离
            while (Mathf.Abs(content.transform.localPosition.x - endPos.x) >= cellWidth / 4)
            {
                yield return null;
                content.localPosition = Vector3.MoveTowards(content.localPosition, endPos, nMoverSpeed);
                if (content.localPosition.x >= 0)
                {
                    break;
                }
            }
        }

        content.localPosition = endPos;
    }

    #endregion
}

滚动分页 展示当前第几分页

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;
using UnityEngine.EventSystems;

/**
 * @des:滚动分页 展示当前第几分页
 * @author:龙建
 * @date:2020-03-05
*/

public class UIScrollViewPageFlag : MonoBehaviour
{
    //public UIWarpContent m_uiWarpContent;
    public GameObject m_flagObg;
    public GameObject m_Grid;

    private const int m_minPageNum = 3;//最少的分页

    private List<PageFlagItem> m_listPageFlage = new List<PageFlagItem>();

    private void Awake()
    {
        if (m_flagObg == null)
        {
            m_flagObg = this.transform.Find("flagItem").gameObject;
        }

        if (m_flagObg == null)
        {
            Debug.LogError("flagItem is bull");
        }

        if (m_Grid == null)
        {
            m_Grid = this.transform.Find("FlagParent/Grid").gameObject;
        }

        if (m_Grid == null)
        {
            Debug.LogError("Grid is bull");
        }
    }


    public void InitPageFlag(int pageNum)
    {
        m_listPageFlage.Clear();
        for (int i = 0; i < m_minPageNum; i++)
        {
            GameObject go = GameObject.Instantiate(m_flagObg);
            go.transform.parent = m_Grid.transform;
            go.SetActive(true);
            PageFlagItem pageFlagItem = go.AddComponent<PageFlagItem>();
            m_listPageFlage.Add(pageFlagItem);
        }
        bool isLastPage = pageNum > 1 ? false : true;
        UpdatePage(1, isLastPage);
    }

    public void UpdatePage(int curPage, bool isLastPage)
    {
        int count = m_listPageFlage.Count;
        int indexShow = curPage % m_minPageNum;

        for (int i = 0; i < count; i++)
        {
            m_listPageFlage[i].m_image.gameObject.SetActive(false);
            m_listPageFlage[i].m_text.gameObject.SetActive(false);
        }

        if (indexShow != 0)
        {
            m_listPageFlage[indexShow - 1].m_text.text = curPage.ToString();
            m_listPageFlage[indexShow - 1].m_text.gameObject.SetActive(true);

        }
        else
        {
            m_listPageFlage[count - 1].m_text.text = curPage.ToString();
            m_listPageFlage[count - 1].m_text.gameObject.SetActive(true);
        }

        //当前页是最后一页
        if(isLastPage && indexShow != 0)
        {
            for (int i = indexShow; i < count; i++)
            {
                m_listPageFlage[i].m_image.gameObject.SetActive(true);
            }
        }
    }
}

public class PageFlagItem : MonoBehaviour
{
    public Image m_image;
    public Text m_text;

    private void Awake()
    {
        m_image = this.transform.Find("Image").GetComponent<Image>();
        m_text = this.transform.Find("Text").GetComponent<Text>();
    }
}


在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值