NGUI优化ScroolView中Grid子级太多导致的滑动问题

当ScrollView中Grid子级太多的时候,会导致卡顿的效果。通过重写MultiRowWrapContent的函数即可有效解决。只需要在Grid上绑定这一个脚本,填写Item的数量,以及单元格大小,滑动的时候就会自动调整Item位置,来实现完美的显示效果。
using UnityEngine;


public class MultiRowWrapContent : UIWrapContent
{


    /// 
    /// 根据数据设置大小
    /// 
    /// 最多显示的大小
    /// 数据长度
    public void SetCurData(int showCount,int dataCount)
    {
        minIndex = 0;
        maxIndex = dataCount - 1;


        if (maxIndex < (showCount-1))
        {
            maxIndex = showCount-1;
        }
    }


    public void mFWrapContent()
    {
        //itemSizeH = 180;
        mFirstTime = true;
        SortBasedOnScrollMovement();
        WrapContent();
        mFirstTime = false;
    }


    protected override void ResetChildPositions()
    {
        for (int i = 0, imax = mChildren.Count; i < imax; ++i)
        {
            Transform t = mChildren[i];


            int x = i * itemSize;
            int y = 0;
            if (!mHorizontal)
            {
                x = (i % RowNum) * itemSize;
                y = -(i / RowNum) * itemSizeH;
                int index = int.Parse(t.gameObject.name.Substring(4,2));//item00
                if (index % 4 == 0)
                    Debug.Log(i+t.gameObject.name+": " + y);
            }


            t.localPosition = new Vector3(x, y, 0);
            UpdateItem(t, i);
        }
    }


    protected override void UpdateItem(Transform item, int index)
    {
        if (onInitializeItem != null)
        {
            int yIndex = Mathf.Abs(Mathf.RoundToInt(item.localPosition.y / itemSize));
            int xIndex = Mathf.Abs(Mathf.RoundToInt(item.localPosition.x / itemSize));
            int realIndex = RowNum * yIndex + xIndex;
            onInitializeItem(item.gameObject, index, realIndex);
        }
    }


    public override void SortBasedOnScrollMovement()
    {
        if (!CacheScrollView()) return;


        // Cache all children and place them in order
        mChildren.Clear();
        for (int i = 0; i < mTrans.childCount; ++i)
        {
            Transform t = mTrans.GetChild(i);
            if (hideInactive && !t.gameObject.activeInHierarchy) continue;
            mChildren.Add(t);
        }


        ResetChildPositions();
    }


    public override void WrapContent()
    {
        float extents = itemSize * (mChildren.Count / RowNum) * 0.5f;
        Vector3[] corners = mPanel.worldCorners;


        for (int i = 0; i < 4; ++i)
        {
            Vector3 v = corners[i];
            v = mTrans.InverseTransformPoint(v);
            corners[i] = v;
        }


        Vector3 center = Vector3.Lerp(corners[0], corners[2], 0.5f);
        bool allWithinRange = true;
        float ext2 = extents * 2f;


        if (mHorizontal)
        {
            float min = corners[0].x - itemSize;
            float max = corners[2].x + itemSize;


            for (int i = 0, imax = mChildren.Count; i < imax; ++i)
            {
                Transform t = mChildren[i];
                float distance = t.localPosition.x - center.x;
                if (distance < -extents)
                {
                    Vector3 pos = t.localPosition;
                    pos.x += ext2;
                    distance = pos.x - center.x;
                    int realIndex = Mathf.RoundToInt(pos.x / itemSize);


                    if (minIndex == maxIndex || (minIndex <= realIndex && realIndex <= maxIndex))
                    {
                        t.localPosition = pos;
                        UpdateItem(t, i);
                    }
                    else allWithinRange = false;
                }
                else if (distance > extents)
                {
                    Vector3 pos = t.localPosition;
                    pos.x -= ext2;
                    distance = pos.x - center.x;
                    int realIndex = Mathf.RoundToInt(pos.x / itemSize);


                    if (minIndex == maxIndex || (minIndex <= realIndex && realIndex <= maxIndex))
                    {
                        t.localPosition = pos;
                        UpdateItem(t, i);
                    }
                    else allWithinRange = false;
                }
                else if (mFirstTime) UpdateItem(t, i);


                if (cullContent)
                {
                    distance += mPanel.clipOffset.x - mTrans.localPosition.x;
                    if (!UICamera.IsPressed(t.gameObject))
                        NGUITools.SetActive(t.gameObject, (distance > min && distance < max), false);
                }
            }
        }
        else
        {
            extents = itemSizeH * (mChildren.Count / RowNum) * 0.5f;
            ext2 = extents * 2f;


            float min = corners[0].y - itemSizeH;
            float max = corners[2].y + itemSizeH;
            for (int i = 0, imax = mChildren.Count; i < imax; ++i)
            {
                Transform t = mChildren[i];
                float distance = t.localPosition.y - center.y;
           
                if (distance < -extents)
                {
                    Vector3 pos = t.localPosition;
                    pos.y += ext2;
                    distance = pos.y - center.y;
                    int yIndex = -Mathf.RoundToInt(pos.y / itemSizeH);
                    int xIndex = -Mathf.RoundToInt(pos.x / itemSize);


                    int realIndex = RowNum * yIndex;
                
                    if (minIndex == maxIndex || (minIndex <= realIndex && realIndex <= maxIndex))
                    {
                        t.localPosition = pos;
                        UpdateItem(t, i);
                    }
                    else allWithinRange = false;
                }
                else if (distance > extents)
                {
                    Vector3 pos = t.localPosition;
                    pos.y -= ext2;
                    distance = pos.y - center.y;
                 //   int realIndex = Mathf.RoundToInt(pos.y / itemSize);
                  //  int yIndex = Mathf.Abs(Mathf.RoundToInt(pos.y / itemSize));
                   // int xIndex = Mathf.Abs(Mathf.RoundToInt(pos.x / itemSize));
                    int yIndex = -Mathf.RoundToInt(pos.y / itemSizeH);
                    int xIndex = -Mathf.RoundToInt(pos.x / itemSize);
                    int realIndex = RowNum * yIndex;
                    
                    if (minIndex == maxIndex || (minIndex <= realIndex && realIndex <= maxIndex))
                    {
                        t.localPosition = pos;
                        UpdateItem(t, i);
                    }
                    else allWithinRange = false;
                }
                else if (mFirstTime) UpdateItem(t, i);


                if (cullContent)
                {
                    distance += mPanel.clipOffset.y - mTrans.localPosition.y;
                    if (!UICamera.IsPressed(t.gameObject))
                        NGUITools.SetActive(t.gameObject, (distance > min && distance < max), false);
                }
            }
        }
        mScroll.restrictWithinPanel = !allWithinRange;
        mScroll.InvalidateBounds();
    }
}




你可能感兴趣的:(Unity,Unity)