• 优化 滑动列表


    using UnityEngine;
    using System.Collections.Generic;
    using System.Collections;
    
    /// <summary>
    /// This script makes it possible for a scroll view to wrap its content, creating endless scroll views.
    /// Usage: simply attach this script underneath your scroll view where you would normally place a UIGrid:
    /// 
    /// + ScrollView(PanelMove)
    /// |- SUIWrapContent(Items)
    /// |-- Item 1
    /// |-- Item 2
    /// |-- Item 3
    /// </summary>
    
    [AddComponentMenu("Custom/SUIWrapContent")]
    
    
    public enum WrapType
    {
        RightSide = 1,
        LeftSide,
        UpSide,
    }
    public class SUIWrapContent : MonoBehaviour
    {
        public static SUIWrapContent Get(GameObject go)
        {
            SUIWrapContent wrap = go.GetComponent<SUIWrapContent>();
            if (wrap == null) wrap = go.AddComponent<SUIWrapContent>();
            return wrap;
        }
    
        /// <summary>列表成员尺寸</summary>
        public Vector2 itemSize = new Vector2(100.0f, 100.0f);
    
        /// <summary>超出UIPanel是否激死</summary>
        public bool cullContent = false;
    
        /// <summary>列表第一个成员的定位点</summary>
        public float first = 0.0f;
        /// <summary>列表首序号</summary>
        public int from = 0;
        /// <summary>列表尾序号</summary>
        public int to = 9;
        /// <summary>列表总成员个数</summary>
        public int maxNum = 100;
    
        /// <summary>列表首标志</summary>
        public UISprite spriteStart;
        /// <summary>列表尾标志</summary>
        public UISprite spriteEnd;
        /// <summary>列表首之前组</summary>
        public Transform groupBeforeStart;
        /// <summary>列表尾之后组</summary>
        public Transform groupAfterEnd;
    
        /// <summary>自动居中</summary>
        public bool autoCenter = false;
        /// <summary>启动复位列表</summary>
        public bool resetOnStart = false;
        /// <summary>灵敏度</summary>
        private float momentumAmount = 60.0f;
        /// <summary>是否循环列表</summary>
        public bool wrapContent = true;
    
        public delegate void Callback(GameObject item, int index);
        /// <summary>更新列表成员数据回调接口</summary>
        public Callback updateItemCallback = null;
        /// <summary>列表成员飞入完成回调接口</summary>
        public Callback moveEffectFinishCallback = null;
        /// <summary>列表成员点击事件回调接口</summary>
        public UIEventListener.VoidDelegate clickCallback = null;
        /// <summary>列表成员自动居中回调接口</summary>
        public UIEventListener.VoidDelegate centerCallback = null;
    
        private Transform mTrans;
        private UIScrollView mScroll;
        private bool mHorizontal = false;
        private List<Transform> mChildren = new List<Transform>();
    
        private bool mStopYieldFlag = false;
        private bool mResetOverFlag = true;
    
    
        public WrapType WrapContentType = WrapType.RightSide;//;
        void Start()
        {
            if (resetOnStart == true)
            {
                Reset(true);
            }
        }
    
        #region 复位处理
        public void Reset(bool moveEffect)
        {
            if(this.gameObject.activeInHierarchy)
               StartCoroutine(DelayReset(moveEffect));
        }
    
        IEnumerator DelayReset(bool moveEffect)
        {
            mResetOverFlag = false;
            yield return 1;
            if (mStopYieldFlag == true) { yield break; }
            SortBasedOnScrollMovement(moveEffect);
            if (mScroll != null && mScroll.panel != null)
            {
                SpringPanel spring = mScroll.panel.GetComponent<SpringPanel>();
                if (spring != null)
                {
                    Destroy(spring);
                }
                if (mInitPanelOffset == false)
                {
                    mPanelClipOffset = mScroll.panel.clipOffset;
                    mPanleLocalPosition = mScroll.panel.transform.localPosition;
                    mInitPanelOffset = true;
                }
                ResetPanelClipOffset();
                mScroll.UpdateScrollbars(true);
                //mScroll.onPressUp = OnPressUp;
                mScroll.panel.onClipMove = OnMove;
                mScroll.disableDragIfFits = false;
                if (autoCenter)
                {
                    mScroll.momentumAmount = momentumAmount * 0.7f;
                }
                else
                {
                    mScroll.momentumAmount = momentumAmount;
                }
            }
    
            mResetOverFlag = true;
        }
    
        private Vector2 mPanelClipOffset = Vector2.zero;
        private Vector3 mPanleLocalPosition = Vector3.zero;
        private bool mInitPanelOffset = false;
    
        private void ResetPanelClipOffset()
        {
            if (mScroll != null && mScroll.panel != null)
            {
                float baseFirst = first;
                if (groupBeforeStart != null && baseFirst <= 0.0f)
                {
                    baseFirst -= 1.0f;
                }
                if (autoCenter == true)
                {
                    if (baseFirst >= 0.0f)
                    {
                        baseFirst = (int)baseFirst;
                    }
                    else
                    {
                        baseFirst = -1.0f;
                    }
                }
                float modifyOffset = 0.0f;
                if (mHorizontal)
                {
                    if (autoCenter == true)
                    {
                        modifyOffset = itemSize.x / 2.0f - mScroll.panel.finalClipRegion.z / 2.0f;
                    }
                    mScroll.panel.clipOffset = mPanelClipOffset + new Vector2(itemSize.x, 0.0f) * baseFirst + new Vector2(modifyOffset,0.0f);
                    mScroll.panel.transform.localPosition = mPanleLocalPosition - new Vector3(itemSize.x, 0.0f, 0.0f) * baseFirst - new Vector3(modifyOffset,0.0f,0.0f);
                }
                else
                {
                    if (autoCenter == true)
                    {
                        modifyOffset = itemSize.y / 2.0f - mScroll.panel.finalClipRegion.w / 2.0f;
                    }
                    mScroll.panel.clipOffset = mPanelClipOffset - new Vector2(0.0f, itemSize.y) * baseFirst - new Vector2(0.0f, modifyOffset);
                    mScroll.panel.transform.localPosition = mPanleLocalPosition + new Vector3(0.0f, itemSize.y, 0.0f) * baseFirst + new Vector3(0.0f,modifyOffset, 0.0f);
                }
                //mScroll.panel.Refresh();
            }
        }
        #endregion
    
        #region 自动居中处理
        void OnPressUp()
        {
            if (autoCenter)
            {
                ReCenter();
            }
        }
    
        private float nextPageThreshold = 0f;
        private GameObject mCenteredObject;
    
        [ContextMenu("ReCenter")]
        public void ReCenter()
        {
            if (mScroll != null && mScroll.panel != null)
            {
                if (maxNum == 0)
                {
                    return;
                }
                // Calculate the panel's center in world coordinates
                Vector3[] corners = mScroll.panel.worldCorners;
                Vector3 panelCenter = (corners[2] + corners[0]) * 0.5f;
    
                // Offset this value by the momentum
                Vector3 momentum = mScroll.currentMomentum * mScroll.momentumAmount;
                Vector3 moveDelta = NGUIMath.SpringDampen(ref momentum, 9f, 2f);
                Vector3 pickingPoint = panelCenter - moveDelta * 0.05f; // Magic number based on what "feels right"
                mScroll.currentMomentum = Vector3.zero;
    
                float min = float.MaxValue;
                Transform closest = null;
                int index = 0;
    
                // Determine the closest child
                for (int i = 0; i < mChildren.Count; ++i)
                {
                    Transform t = mChildren[i];
                    if (!t.gameObject.activeInHierarchy) continue;
                    float sqrDist = Vector3.SqrMagnitude(t.position - pickingPoint);
    
                    if (sqrDist < min)
                    {
                        min = sqrDist;
                        closest = t;
                        index = i;
                    }
                }
    
                // If we have a touch in progress and the next page threshold set
                if (nextPageThreshold > 0f && UICamera.currentTouch != null)
                {
                    // If we're still on the same object
                    if (mCenteredObject != null && mCenteredObject.transform == mChildren[index])
                    {
                        Vector2 totalDelta = UICamera.currentTouch.totalDelta;
    
                        float delta = 0f;
    
                        switch (mScroll.movement)
                        {
                            case UIScrollView.Movement.Horizontal:
                                {
                                    delta = totalDelta.x;
                                    break;
                                }
                            case UIScrollView.Movement.Vertical:
                                {
                                    delta = totalDelta.y;
                                    break;
                                }
                            default:
                                {
                                    delta = totalDelta.magnitude;
                                    break;
                                }
                        }
    
                        if (delta > nextPageThreshold)
                        {
                            // Next page
                            if (index > 0)
                                closest = mChildren[index-1];
                        }
                        else if (delta < -nextPageThreshold)
                        {
                            // Previous page
                            if (index < mChildren.Count - 1)
                                closest = mChildren[index+1];
                        }
                    }
                }
    
                CenterOn(closest, panelCenter);
            }
        }
        /// <summary>
        /// Center the panel on the specified target.
        /// </summary>
        void CenterOn(Transform target, Vector3 panelCenter)
        {
            if (target != null && mScroll != null && mScroll.panel != null)
            {
                Transform panelTrans = mScroll.panel.cachedTransform;
                mCenteredObject = target.gameObject;
                // Figure out the difference between the chosen child and the panel's center in local coordinates
                Vector3 cp = panelTrans.InverseTransformPoint(target.position);
                Vector3 cc = panelTrans.InverseTransformPoint(panelCenter);
                Vector3 localOffset = cp - cc;
    
                // Offset shouldn't occur if blocked
                if (!mScroll.canMoveHorizontally) localOffset.x = 0f;
                if (!mScroll.canMoveVertically) localOffset.y = 0f;
                localOffset.z = 0f;
    
                // Spring the panel to this calculated position
    #if UNITY_EDITOR
                if (!Application.isPlaying)
                {
                    panelTrans.localPosition = panelTrans.localPosition - localOffset;
    
                    Vector4 co = mScroll.panel.clipOffset;
                    co.x += localOffset.x;
                    co.y += localOffset.y;
                    mScroll.panel.clipOffset = co;
                }
                else
    #endif
                {
                    SpringPanel.Begin(mScroll.panel.cachedGameObject, panelTrans.localPosition - localOffset, 10);//.onFinished = onFinished
                }
    
                // Notify the listener
                if (centerCallback != null)
                {
                    centerCallback(mCenteredObject);
                }
            }
            else
            {
                mCenteredObject = null;
            }
        }
        #endregion
    
        /// <summary>
        /// Callback triggered by the UIPanel when its clipping region moves (for example when it's being scrolled).
        /// </summary>
        protected virtual void OnMove (UIPanel panel) 
        { 
            if (mResetOverFlag == true)
            {
                if (wrapContent)
                {
                    WrapContent();
                }
            }
        }
    
        /// <summary>
        /// Immediately reposition all children.
        /// </summary>
        [ContextMenu("Sort Based on Scroll Movement")]
        public void SortBasedOnScrollMovement(bool moveEffect)
        {
            if (!CacheScrollView()) return;
    
            float maxFirst = from;
            int needNum = maxNum;
            if (wrapContent)
            {
                if (mHorizontal)
                {
                    maxFirst = maxNum - mScroll.panel.finalClipRegion.z / itemSize.x;
                    needNum = (int)(mScroll.panel.finalClipRegion.z / itemSize.x) + 2;
                }
                else
                {
                    maxFirst = maxNum - mScroll.panel.finalClipRegion.z / itemSize.x;
                    needNum = (int)(mScroll.panel.finalClipRegion.w / itemSize.y) + 2;
                }
                if (first < 0.0f)
                {
                    first = 0.0f;
                }
                else if (first > maxFirst && maxFirst > 0.0f)
                {
                    first = maxFirst;
                }
                from = (int)first;
                if (from > 0)
                {
                    from -= 1;
                }
                to = from + needNum - 1;
                if (to > maxNum - 1)
                {
                    to = maxNum - 1;
                    from = to - needNum + 1;
                    if (from < 0)
                    {
                        from = 0;
                    }
                }
            }
            else
            {
                to = maxNum - 1;
            }
    
            if (to < 0)
            {
                to = 0;
            }
    
            if (mTrans.childCount < needNum)
            {
                if (mTrans.childCount > 0)
                {
                    Transform item = mTrans.GetChild(0);
                    int max = needNum - mTrans.childCount;
                    for (int i = 0; i < max; ++i)
                    {
                        NGUITools.AddChild(this.gameObject, item.gameObject);
                    }
                }
            }
    
            // Cache all children and place them in order
            mChildren.Clear();
            if (mTrans.childCount > 0)
            {
                for (int i = 0; i < mTrans.childCount; ++i)
                {
                    Transform tran = mTrans.GetChild(i);
    
                    List<BoxCollider> boxs = GetComponentsAll<BoxCollider>(tran.gameObject, true);
                    if (boxs != null && boxs.Count > 0)
                    {
                        for (int j = 0; j < boxs.Count; j++)
                        {
                            BoxCollider box = boxs[j];
                            if (clickCallback != null)
                            {
                                UIEventListener.Get(box.gameObject).onClick = clickCallback;
                            }
                            UIDragScrollView drag = box.GetComponent<UIDragScrollView>();
                            if (drag == null)
                            {
                                drag = box.gameObject.AddComponent<UIDragScrollView>();
                            }
                            if (drag.scrollView == null)
                            {
                                drag.scrollView = mScroll;
                            }
                        }
                    }
                    mChildren.Add(tran);
                }
            }
    
            if (mChildren.Count > 0)
            {
                // Sort the list of children so that they are in order
                if (mHorizontal) mChildren.Sort(UIGrid.SortHorizontal);
                else mChildren.Sort(UIGrid.SortVertical);
            }
            
            ResetChildPositions(moveEffect);
        }
    
    
        /// <summary>获取对象上及子对象上所有的组件</summary>
        private List<T> GetComponentsAll<T>(GameObject go, bool includeInactive) where T : Component
        {
            List<T> listT = new List<T>();
            if (go != null)
            {
                T t = go.GetComponent<T>();
                if (t != null)
                {
                    listT.Add(t);
                }
                T[] ts = go.GetComponentsInChildren<T>(includeInactive);
                if (ts != null)
                {
                    for (int i = 0, max = ts.Length; i < max; i++)
                    {
                        T tt = ts[i];
                        listT.Add(tt);
                    }
                }
            }
            return listT;
        }
    
        /// <summary>
        /// Immediately reposition all children, sorting them alphabetically.
        /// </summary>
        [ContextMenu("Sort Alphabetically")]
        public void SortAlphabetically ()
        {
            if (!CacheScrollView()) return;
    
            // Cache all children and place them in order
            mChildren.Clear();
            for (int i = 0; i < mTrans.childCount; ++i)
                mChildren.Add(mTrans.GetChild(i));
    
            // Sort the list of children so that they are in order
            mChildren.Sort(UIGrid.SortByName);
            ResetChildPositions(false);
        }
    
        /// <summary>
        /// Cache the scroll view and return 'false' if the scroll view is not found.
        /// </summary>
        protected bool CacheScrollView ()
        {
            mTrans = transform;
            mScroll = NGUITools.FindInParents<UIScrollView>(gameObject);
    
            if (mScroll == null) return false;
            if (mScroll.movement == UIScrollView.Movement.Horizontal) mHorizontal = true;
            else if (mScroll.movement == UIScrollView.Movement.Vertical) mHorizontal = false;
            else return false;
    
            return true;
        }
    
        private Vector3 mClipTopLeftPos = Vector3.zero;
    
        /// <summary>
        /// Helper function that resets the position of all the children.
        /// </summary>
        void ResetChildPositions (bool moveEffect)
        {
            mClipTopLeftPos = new Vector3(-mScroll.panel.finalClipRegion.z / 2.0f + mScroll.panel.clipSoftness.x, mScroll.panel.finalClipRegion.w / 2.0f - mScroll.panel.clipSoftness.y, 0.0f);
            mListSpringPosition.Clear();
            //---
            if (spriteStart != null)
            {
                spriteStart.width = (int)itemSize.x;
                spriteStart.height = (int)itemSize.y;
                //spriteStart.color = new Color(0.0f, 0.0f, 0.0f, 1.0f / 255.0f);
                spriteStart.transform.localPosition = mHorizontal ? new Vector3(mClipTopLeftPos.x + itemSize.x / 2.0f, 0f, 0f) : new Vector3(0f, mClipTopLeftPos.y - itemSize.y / 2.0f, 0f);
                if (spriteStart.gameObject.activeSelf == false)
                {
                    spriteStart.gameObject.SetActive(true);
                }
            }
            if (spriteEnd != null)
            {
                int index = maxNum - 1;
                if (index < 0)
                {
                    index = 0;
                }
                spriteEnd.width = (int)itemSize.x;
                spriteEnd.height = (int)itemSize.y;
                //spriteEnd.color = new Color(0.0f, 0.0f, 0.0f, 1.0f / 255.0f);
                spriteEnd.transform.localPosition = mHorizontal ? new Vector3(mClipTopLeftPos.x + itemSize.x / 2.0f + (float)(index) * itemSize.x, 0f, 0f) : new Vector3(0f, mClipTopLeftPos.y - itemSize.y / 2.0f - (float)(index) * itemSize.y, 0f);
                if (spriteEnd.gameObject.activeSelf == false)
                {
                    spriteEnd.gameObject.SetActive(true);
                }
            }
            int moveIndex = 1;
            if (groupBeforeStart != null)
            {
                groupBeforeStart.localPosition = mHorizontal ? new Vector3(mClipTopLeftPos.x - itemSize.x / 2.0f, 0f, 0f) : new Vector3(0f, mClipTopLeftPos.y + itemSize.y / 2.0f, 0f);
                if (groupBeforeStart.gameObject.activeSelf == false)
                {
                    groupBeforeStart.gameObject.SetActive(true);
                }
                if (moveEffect == true)
                {
                    AddMoveEffect(groupBeforeStart.gameObject, moveIndex, false);
                    moveIndex++;
                }
            }
            //---
            for (int i = 0; i < mChildren.Count; ++i)
            {
                Transform t = mChildren[i];
                int index = (from + i);
                t.gameObject.name = index.ToString();
                t.localPosition = mHorizontal ? new Vector3(mClipTopLeftPos.x + itemSize.x / 2.0f + index * itemSize.x, 0f, 0f) : new Vector3(0f, mClipTopLeftPos.y - itemSize.y / 2.0f - index * itemSize.y, 0f);
                if (index >= 0 && index < maxNum)
                {
                    t.gameObject.SetActive(true);
                    if (moveEffect == true)
                    {
                        AddMoveEffect(t.gameObject, moveIndex, true);
                        moveIndex++;
                        if (mScroll.enabled == true)
                        {
                            mScroll.enabled = false;
                        }
                    }
    
                    UpdateItem(t, index);
                }
                else
                {
                    t.gameObject.SetActive(false);
                }
            }
            if (groupAfterEnd != null)
            {
                groupAfterEnd.localPosition = mHorizontal ? new Vector3(mClipTopLeftPos.x + itemSize.x / 2.0f + (float)(maxNum) * itemSize.x, 0f, 0f) : new Vector3(0f, mClipTopLeftPos.y - itemSize.y / 2.0f - (float)(maxNum) * itemSize.y, 0f);
                if (groupAfterEnd.gameObject.activeSelf == false)
                {
                    groupAfterEnd.gameObject.SetActive(true);
                }
                if (moveEffect == true)
                {
                    AddMoveEffect(groupAfterEnd.gameObject, moveIndex, false);
                    moveIndex++;
                }
            }
        }
        void AddMoveEffect(GameObject item, int index, bool addList)
        {
            Vector3 pos = item.transform.localPosition;
            switch (WrapContentType)
            {
                case WrapType.RightSide:
                    item.transform.localPosition += new Vector3(mScroll.panel.finalClipRegion.z * (float)(index), 0.0f, 0.0f);
                    break;
                case WrapType.UpSide: 
                    item.transform.localPosition += new Vector3(0.0f, mScroll.bounds.size.y + mScroll.panel.finalClipRegion.w * (float)(index), 0.0f);
                    break;
                case WrapType.LeftSide:
                    item.transform.localPosition += new Vector3(-1*mScroll.panel.finalClipRegion.z * (float)(index), 0.0f, 0.0f);
                    break;
            }
            SSpringPosition sp = SSpringPosition.Begin(item, pos, 10.0f);
            sp.onFinished = MoveEffectFinishOver;
            if (addList == true)
            {
                mListSpringPosition.Add(sp);
            }
            //Vector3 pos = item.transform.localPosition;
            //
            //SSpringPosition sp = SSpringPosition.Begin(item, pos, 10.0f);
            //sp.onFinished = MoveEffectFinishOver;
            //if (addList == true)
            //{
            //    mListSpringPosition.Add(sp);
            //}
        }
        private List<SSpringPosition> mListSpringPosition = new List<SSpringPosition>();
        void MoveEffectFinishOver(SSpringPosition sp)
        {
            GameObject item = sp.gameObject;
            if (item != null)
            {
                int index = -1;
                int.TryParse(item.name, out index);
                if (index >= 0 && index < maxNum)
                {
                    if (moveEffectFinishCallback != null)
                    {
                        moveEffectFinishCallback(item, index);
                    }
                }
            } 
            mListSpringPosition.Remove(sp);
            if (mListSpringPosition.Count <= 0)
            {
                if (mScroll.enabled == false)
                {
                    mScroll.enabled = true;
                }
            }
        }
    
        /// <summary>
        /// Wrap all content, repositioning all children as needed.
        /// </summary>
        public void WrapContent ()
        {
            Vector3[] corners = mScroll.panel.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);
    
            if (mHorizontal)
            {
                float extents = itemSize.x * mChildren.Count * 0.5f;
                float ext2 = extents * 2f;
                float min = corners[0].x - itemSize.x;
                float max = corners[2].x + itemSize.x;
    
                for (int i = 0; i < mChildren.Count; ++i)
                {
                    Transform t = mChildren[i];
                    float distance = t.localPosition.x - center.x;
                    Vector3 pos = t.localPosition;
                    bool modify = false;
    
                    if (distance < -extents)
                    {
                        pos.x += ext2;
                        distance = pos.x - center.x;
                        modify = true;
                    }
                    else if (distance > extents)
                    {
                        pos.x -= ext2;
                        distance = pos.x - center.x;
                        modify = true;
                    }
                    if (modify == true)
                    {
                        int index = GetIndex(pos);
                        if (index >= 0 && index < maxNum)
                        {
                            if (index < from)
                            {
                                to -= from - index;
                                from = index;
                            }
                            else if (index > to)
                            {
                                from += index - to;
                                to = index;
                            }
                            t.localPosition = pos;
                            UpdateItem(t, index);
                        }
                    }
                    
                    if (cullContent)
                    {
                        distance += mScroll.panel.clipOffset.x - mTrans.localPosition.x;
                        if (!UICamera.IsPressed(t.gameObject))
                            NGUITools.SetActive(t.gameObject, (distance > min && distance < max), false);
                    }
                }
            }
            else
            {
                float extents = itemSize.y * mChildren.Count * 0.5f;
                float ext2 = extents * 2f;
                float min = corners[0].y - itemSize.y;
                float max = corners[2].y + itemSize.y;
    
                for (int i = 0; i < mChildren.Count; ++i)
                {
                    Transform t = mChildren[i];
                    float distance = t.localPosition.y - center.y;
                    Vector3 pos = t.localPosition;
                    bool modify = false;
    
                    if (distance < -extents)
                    {
                        pos.y += ext2;
                        distance = pos.y - center.y;
                        modify = true;
                    }
                    else if (distance > extents)
                    {
                        pos.y -= ext2;
                        distance = pos.y - center.y;
                        modify = true;
                    }
                    
                    if (modify == true)
                    {
                        int index = GetIndex(pos);
                        if (index >= 0 && index < maxNum)
                        {
                            if (index < from)
                            {
                                to -= from - index;
                                from = index;
                            }
                            else if (index > to)
                            {
                                from += index - to;
                                to = index;
                            }
                            t.localPosition = pos;
                            UpdateItem(t, index);
                        }
                    }
    
                    if (cullContent)
                    {
                        distance += mScroll.panel.clipOffset.y - mTrans.localPosition.y;
                        if (!UICamera.IsPressed(t.gameObject))
                            NGUITools.SetActive(t.gameObject, (distance > min && distance < max), false);
                    }
                }
            }
        }
    
        /// <summary>
        /// Want to update the content of items as they are scrolled? Override this function.
        /// </summary>
        protected virtual void UpdateItem (Transform item, int index)
        {
            if (item != null)
            {
                item.gameObject.name = index.ToString();
                if (index >= 0 && index < maxNum)
                {
                    if (item.gameObject.activeSelf == false)
                    {
                        item.gameObject.SetActive(true);
                    }
                    if (updateItemCallback != null)
                    {
                        updateItemCallback(item.gameObject, index);
                    }
                }
                else
                {
                    if (item.gameObject.activeSelf == true)
                    {
                        item.gameObject.SetActive(false);
                    }
                }
                //Debugger.Log(string.Format("UpdateItem={0}",index.ToString()));
            }
        }
        /// <summary>
        /// 更新滑动控件
        /// </summary>
        private void UpdateScrowView()
        {
            if (spriteEnd != null)
            {
                int index = maxNum - 1;
                if (index < 0)
                {
                    index = 0;
                }
                spriteEnd.transform.localPosition = mHorizontal ? new Vector3(mClipTopLeftPos.x + itemSize.x / 2.0f + (float)(index) * itemSize.x, 0f, 0f) : new Vector3(0f, mClipTopLeftPos.y - itemSize.y / 2.0f - (float)(index) * itemSize.y, 0f);
            }
            if (groupAfterEnd != null)
            {
                groupAfterEnd.localPosition = mHorizontal ? new Vector3(mClipTopLeftPos.x + itemSize.x / 2.0f + (float)(maxNum) * itemSize.x, 0f, 0f) : new Vector3(0f, mClipTopLeftPos.y - itemSize.y / 2.0f - (float)(maxNum) * itemSize.y, 0f);
            }
            if (mScroll != null)
            {
                mScroll.UpdateScrollbars(true);
            }
        }
        
        #region 外部接口
        /// <summary>
        /// 获取成员序号
        /// </summary>
        /// <param name="item">成员对象</param>
        /// <returns>序号</returns>
        public int GetIndex(GameObject item)
        {
            int index = -1;
            if (item != null)
            {
                index = GetIndex(item.transform.localPosition);
            }
            return index;
        }
        public int GetIndex(Vector3 pos)
        {
            int index = -1;
            if (mHorizontal)
            {
                if (pos.x > mClipTopLeftPos.x)
                {
                    index = (int)((pos.x - mClipTopLeftPos.x) / itemSize.x);
                }
            } 
            else
            {
                if (pos.y < mClipTopLeftPos.y)
                {
                    index = (int)((-pos.y + mClipTopLeftPos.y) / itemSize.y);
                }
            }
            return index;
        }
        /// <summary>
        /// 获取指定列表成员坐标
        /// </summary>
        /// <param name="index">指定序号</param>
        /// <returns>列表成员坐标</returns>
        public Vector3 GetItemPosByIndex(int index)
        {
            Vector3 pos = Vector3.zero;
            if (mHorizontal)
            {
                pos = new Vector3(mClipTopLeftPos.x + itemSize.x / 2.0f + (float)index * itemSize.x, 0.0f, 0.0f);
            }
            else
            {
                pos = new Vector3(0.0f, mClipTopLeftPos.y - itemSize.y / 2.0f - (float)index * itemSize.y, 0.0f);
            }
            return pos;
        }
        /// <summary>
        /// 刷新列表数据
        /// </summary>
        public void RefreshList()
        {
            for (int i = 0; i < mChildren.Count; ++i)
            {
                Transform t = mChildren[i];
                int index = GetIndex(t.gameObject);
                if (index >= from && index <= to)
                {
                    UpdateItem(t, index);
                }
            }
            if (wrapContent)
            {
                WrapContent();
            }
        }
        /// <summary>
        /// 摧毁所有成员
        /// </summary>
        /// <param name="includeModel">是否包含模板Item</param>
        public void DestoryAllItem(bool includeModel)
        {
            maxNum = 0;
            for (int i = 0; i < mChildren.Count; ++i)
            {
                Transform t = mChildren[i];
                if (includeModel == false && i == 0)
                {
                    t.gameObject.SetActive(false);
                }
                else
                {
                    GameObject.Destroy(t.gameObject);
                }
            }
            UpdateScrowView();
            if (wrapContent)
            {
                WrapContent();
            }
        }
        /// <summary>
        /// 移除列表所有成员
        /// </summary>
        public void RemoveAllItem()
        {
            maxNum = 0;
            for (int i = 0; i < mChildren.Count; ++i)
            {
                Transform t = mChildren[i];
                t.gameObject.SetActive(false);
            }
            UpdateScrowView();
            if (wrapContent)
            {
                WrapContent();
            }
        }
        /// <summary>
        /// 移除列表指定成员
        /// </summary>
        /// <param name="item">成员对象</param>
        public void RemoveItem(GameObject item)
        {
            if (item != null)
            {
                int ind = GetIndex(item);
                if (ind >= 0 && ind < maxNum)
                {
                    RemoveItem(ind);
                }
            }
        }
        /// <summary>
        /// 移除列表指定成员
        /// </summary>
        /// <param name="index">序号</param>
        public void RemoveItem(int index)
        {
            if (index < 0 && index >= maxNum)
            {
                return;
            }
            maxNum--;
            for (int i = 0; i < mChildren.Count; ++i)
            {
                Transform t = mChildren[i];
                int ind = GetIndex(t.gameObject); 
                if (ind >= index && ind <= to)
                {
                    UpdateItem(t, ind);
                }
            }
            UpdateScrowView();
            if (wrapContent)
            {
                WrapContent();
            }
        }
        /// <summary>
        /// 插入列表成员
        /// </summary>
        /// <param name="index">指定序号</param>
        public void InsertItem(int index)
        {
            if (index < 0 && index >= maxNum)
            {
                return;
            }
            maxNum++;
            for (int i = 0; i < mChildren.Count; ++i)
            {
                Transform t = mChildren[i];
                int ind = GetIndex(t.gameObject);
                if (ind >= index && ind <= to)
                {
                    UpdateItem(t, ind);
                }
            }
            UpdateScrowView();
            if (wrapContent)
            {
                WrapContent();
            }
        }
        /// <summary>
        /// 追加列表成员
        /// </summary>
        public void AppentItem()
        {
            maxNum++;
            UpdateScrowView();
            if (wrapContent)
            {
                WrapContent();
            }
        }
        /// <summary>
        /// 移动列表
        /// </summary>
        /// <param name="index">指定序号</param>
        public void SpringList(int index)
        {
            if (index < 0 && index >= maxNum)
            {
                return;
            }
            Vector3 panelOffset = GetPanelOffsetByIndex(index);
            Vector3 pos = mPanleLocalPosition;
            if (mHorizontal)
            {
                pos -= new Vector3(panelOffset.x, 0.0f, 0.0f);
                if (autoCenter)
                {
                    pos += new Vector3(-itemSize.x / 2.0f + mScroll.panel.finalClipRegion.z / 2.0f, 0.0f, 0.0f);
                }
            } 
            else
            {
                pos -= new Vector3(0.0f, panelOffset.y, 0.0f);
                if (autoCenter)
                {
                    pos += new Vector3(0.0f, itemSize.y / 2.0f - mScroll.panel.finalClipRegion.w / 2.0f, 0.0f);
                }
            }
            SpringPanel spring = SpringPanel.Begin(mScroll.panel.gameObject, pos, 10);
            spring.onFinished = SpringListFinishCallback;
        }
        void SpringListFinishCallback()
        {
            SpringPanel spring = mScroll.gameObject.GetComponent<SpringPanel>();
            if (spring != null)
            {
                Destroy(spring);
            }
            ReCenter();
        }
        /// <summary>
        /// 获取指定序号裁剪偏移量
        /// </summary>
        /// <param name="index">指定序号</param>
        /// <returns>裁剪偏移量</returns>
        private Vector3 GetPanelOffsetByIndex(int index)
        {
            Vector3 pos = Vector3.zero;
            if (mHorizontal)
            {
                pos = new Vector3(mPanelClipOffset.x + (float)index * itemSize.x, mScroll.panel.clipOffset.y, 0.0f);
            }
            else
            {
                pos = new Vector3(mScroll.panel.clipOffset.x, mPanelClipOffset.y - (float)index * itemSize.y, 0.0f);
            }
            return pos;
        }
        #endregion
    }
  • 相关阅读:
    GSON -JSON 反序列化-多节点名称支持
    Jedis 分片原理
    闭锁-CountDownLatch
    XML序列化及反序列化
    用GIT操作SVN
    报表worker-CPU使用率过高原因排查
    二.PlantUML 之活动图
    一.PlantUML 与 IDEA 集成
    ArrayList
    VI常用命令
  • 原文地址:https://www.cnblogs.com/bambomtan/p/5002107.html
Copyright © 2020-2023  润新知