[UI功能]UGUI 制作上拉加载下拉刷新

使用方法:


image.png

具体使用方法,主要就是控制加载和下拉还有上拉状态的控制。然后只需要自己写一个方法实现mLoadData就可以了。
三大脚本如下:

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

public enum LoadingTipStatus
{
None,
WaitRelease,
WaitLoad,
Loaded,
NoMore,
Failure
}

public enum RequestState {
None,
Success,
Failure,
NoOne
}

public class UI_PullToRefresh : MonoBehaviour {

public LoopListView2 mLoopListView;
public LoadingTipStatus mLoadingTipStatus = LoadingTipStatus.None;
public RequestState state = RequestState.None;
float mDataLoadedTipShowLeftTime = 0;
float mLoadingTipItemHeight = 100;
public delegate LoopListViewItem2 MLoadData(LoopListView2 listView, LoopListViewItem2 item, int index);
public MLoadData mLoadData;
public delegate void LoadBroadcater(UI_Brdata broadcaster,int index);
public LoadBroadcater mLoadBroadcaster;
public int number = 0;
public int mListItemTotalCount = 0;
public bool isInit = false;
public bool isSuccee = false;

public void OnStart()
{
    if (isInit)
    {
        Refresh();
    }
    else
    {
        // totalItemCount +1 because the "pull to refresh" banner is also a item.
        mLoopListView.InitListView(number + 2, OnGetItemByIndex);
        mLoopListView.mOnBeginDragAction = OnBeginDrag;
        mLoopListView.mOnDragingAction = OnDraging;
        mLoopListView.mOnEndDragAction = OnEndDrag;
        isInit = true;
    }
    ReSet();
}

/// <summary>
/// 设置刷新状态为None,关闭刷新组件
/// </summary>

public void ReSet()
{
    if (mLoopListView.ScrollRect == null)
    {
        return;
    }
    //ScrollRect sr = mLoopListView.ScrollRect;
    //Vector3 pos = sr.content.localPosition;
    //if (pos.y == 0) { return; }
    if (mLoadingTipStatus == LoadingTipStatus.None)
    {
        return;
    }
    if (mLoadingTipStatus == LoadingTipStatus.WaitLoad)
    {
        mLoopListView.MovePanelToItemIndex(1, 0);
    }
    mLoadingTipStatus = LoadingTipStatus.None;
    LoopListViewItem2 item = mLoopListView.GetShownItemByItemIndex(0);
    if (item == null)
    {
        return;
    }
    UpdateLoadingTip(item);
    item.CachedRectTransform.localPosition = new Vector3(0, -mLoadingTipItemHeight, 0);
    mLoopListView.OnItemSizeChanged(0);
}

public void Refresh() {
    isSuccee = true;
    mLoopListView.SetListItemCount(number + 2, false);
    FinishRefresh();
}
public void Failed() {
    SetState(RequestState.Failure);
    isSuccee = false;
    number = 0;
    OnStart();
    FinishRefresh();

}
void FinishRefresh()
{
    DataSourceMgr.Get.mIsRefreshDataSuccee = true;
    LoopListViewItem2 item = mLoopListView.GetShownItemByItemIndex(1);
    if (item != null)
    {
        UpdateLogo(item);
    }
}
public void SetState(RequestState state)
{
    this.state = state;
}
public void Close()
{
    mLoopListView.SetListItemCount(0, false);
}

LoopListViewItem2 OnGetItemByIndex(LoopListView2 listView, int index)
{
    if (index < 0 || index > number + 1)
    {
        return null;
    }
    LoopListViewItem2 item = null;
    if (index == 0)
    {
        item = listView.NewListViewItem("ItemPrefab0");
        UpdateLoadingTip(item);
        return item;
    }
    if (index == 1)
    {
        item = listView.NewListViewItem("LogoPanel");
        UpdateLogo(item);
        return item;
    }
  
    return mLoadData(listView, item, index); 
}
void UpdateLogo(LoopListViewItem2 item)
{
    if (item == null)
    {
        return;
    }
    GameObject obj = item.gameObject;
    if (obj == null)
    {
        return;
    }
    if (state == RequestState.None)
    {
        obj.SetActive(false);
        obj.transform.GetChild(0).gameObject.SetActive(false);
        item.CachedRectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, 0);
    }
    else if (state == RequestState.Success)
    {
        obj.SetActive(false);
        obj.transform.GetChild(0).gameObject.SetActive(false);
        item.CachedRectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, 0);
    }
    else if (state == RequestState.Failure)
    {
        obj.SetActive(true);
        obj.transform.GetChild(0).gameObject.SetActive(true);
        obj.transform.GetChild(0).GetChild(0).transform.GetComponent<Text>().text = "网络错误,下拉刷新数据";
        item.CachedRectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, 0);
    }
    else if (state == RequestState.NoOne)
    {
        obj.SetActive(true);
        obj.transform.GetChild(0).gameObject.SetActive(true);
        obj.transform.GetChild(0).GetChild(0).transform.GetComponent<Text>().text = "你还没有关注任何主播哦~";
        item.CachedRectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, 0);
    }
}
void UpdateLoadingTip(LoopListViewItem2 item)
{
    if (item == null)
    {
        return;
    }
    ListItem0 itemScript0 = item.GetComponent<ListItem0>();
    if (itemScript0 == null)
    {
        return;
    }
    if (mLoadingTipStatus == LoadingTipStatus.None)
    {
        itemScript0.mRoot.SetActive(false);
        item.CachedRectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, 0);
    }
    else if (mLoadingTipStatus == LoadingTipStatus.WaitRelease)
    {
        itemScript0.mRoot.SetActive(true);
        //itemScript0.mText.text = "松开刷新";
        //itemScript0.mArrow.SetActive(true);
        itemScript0.mWaitingIcon.SetActive(true);
        item.CachedRectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, mLoadingTipItemHeight);
    }
    else if (mLoadingTipStatus == LoadingTipStatus.WaitLoad)
    {
        itemScript0.mRoot.SetActive(true);
       // itemScript0.mArrow.SetActive(false);
        itemScript0.mWaitingIcon.SetActive(true);
       // itemScript0.mText.text = "刷新中";
        item.CachedRectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, mLoadingTipItemHeight);
    }
    else if (mLoadingTipStatus == LoadingTipStatus.Loaded)
    {
        itemScript0.mRoot.SetActive(true);
      //  itemScript0.mArrow.SetActive(false);
        itemScript0.mWaitingIcon.SetActive(true);
       // itemScript0.mText.text = "刷新成功";
        item.CachedRectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, mLoadingTipItemHeight);
    }
    else if (mLoadingTipStatus == LoadingTipStatus.Failure)
    {
        itemScript0.mRoot.SetActive(true);
        //itemScript0.mArrow.SetActive(false);
        itemScript0.mWaitingIcon.SetActive(true);
        //itemScript0.mText.text = "刷新失败";
        item.CachedRectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, mLoadingTipItemHeight);
    }
}

void OnBeginDrag()
{
    //  mLoadingTipStatus = LoadingTipStatus.None;
}

void OnDraging()
{
    if (mLoopListView.ShownItemCount == 0)
    {
        return;
    }
    if (mLoadingTipStatus != LoadingTipStatus.None && mLoadingTipStatus != LoadingTipStatus.WaitRelease && mLoadingTipStatus != LoadingTipStatus.Failure)
    {
        return;
    }
    LoopListViewItem2 item = mLoopListView.GetShownItemByItemIndex(0);
    if (item == null)
    {
        return;
    }
    ScrollRect sr = mLoopListView.ScrollRect;
    Vector3 pos = sr.content.localPosition;

    if (pos.y < -mLoadingTipItemHeight)
    {
        if (mLoadingTipStatus != LoadingTipStatus.None)
        {
            return;
        }
        mLoadingTipStatus = LoadingTipStatus.WaitRelease;
        UpdateLoadingTip(item);
        item.CachedRectTransform.localPosition = new Vector3(0, mLoadingTipItemHeight, 0);
    }
    else
    {
        if (mLoadingTipStatus != LoadingTipStatus.WaitRelease)
        {
            return;
        }
        mLoadingTipStatus = LoadingTipStatus.None;
        UpdateLoadingTip(item);
        item.CachedRectTransform.localPosition = new Vector3(0, 0, 0);
    }
}
void OnEndDrag()
{
    if (mLoopListView.ShownItemCount == 0)
    {
        return;
    }
    if (mLoadingTipStatus != LoadingTipStatus.None && mLoadingTipStatus != LoadingTipStatus.WaitRelease)
    {
        return;
    }
    LoopListViewItem2 item = mLoopListView.GetShownItemByItemIndex(0);
    if (item == null)
    {
        return;
    }
    mLoopListView.OnItemSizeChanged(item.ItemIndex);
    if (mLoadingTipStatus != LoadingTipStatus.WaitRelease)
    {
        return;
    }
    mLoadingTipStatus = LoadingTipStatus.WaitLoad;
    UpdateLoadingTip(item);
    DataSourceMgr.Get.RequestRefreshDataList(OnDataSourceRefreshFinished);
}

public void ResumeUI() {
    mLoopListView.SetListItemCount(number + 2, false);
    mLoopListView.RefreshAllShownItem();
}
void OnDataSourceRefreshFinished()
{
    if (mLoopListView.ShownItemCount == 0)
    {
        return;
    }
    if (mLoadingTipStatus == LoadingTipStatus.WaitLoad)
    {
        if (isSuccee)
        {
            mLoadingTipStatus = LoadingTipStatus.Loaded;

        }
        else
        {
            mLoadingTipStatus = LoadingTipStatus.Failure;
        }
        mDataLoadedTipShowLeftTime = 0.7f;
        LoopListViewItem2 item = mLoopListView.GetShownItemByItemIndex(0);
        if (item == null)
        {
            return;
        }
        UpdateLoadingTip(item);
        mLoopListView.RefreshAllShownItem();
    }
}
void Update()
{
    if (mLoopListView.ShownItemCount == 0)
    {
        return;
    }
    if (mLoadingTipStatus == LoadingTipStatus.Loaded || mLoadingTipStatus == LoadingTipStatus.Failure)
    {
        mDataLoadedTipShowLeftTime -= Time.deltaTime;
        if (mDataLoadedTipShowLeftTime <= 0)
        {
            mLoadingTipStatus = LoadingTipStatus.None;
            LoopListViewItem2 item = mLoopListView.GetShownItemByItemIndex(0);
            if (item == null)
            {
                return;
            }
            UpdateLoadingTip(item);
            item.CachedRectTransform.localPosition = new Vector3(0, -mLoadingTipItemHeight, 0);
            mLoopListView.OnItemSizeChanged(0);
        }

    }

}
public void Resume()
{
    mLoopListView.OnItemSizeChanged(0);
}

}

附上SuperSCrollView 源码。这段代码是核心
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;

namespace SuperScrollView
{

public enum ItemCornerEnum
{
    LeftBottom = 0,
    LeftTop,
    RightTop,
    RightBottom,
}


public enum ListItemArrangeType
{
    TopToBottom,
    BottomToTop,
    LeftToRight,
    RightToLeft,
}

public class ItemPool
{
    GameObject mPrefabObj;
    string mPrefabName;
    int mInitCreateCount = 1;
    float mPadding = 0;
    float mStartPosOffset = 0;
    List<LoopListViewItem2> mTmpPooledItemList = new List<LoopListViewItem2>();
    List<LoopListViewItem2> mPooledItemList = new List<LoopListViewItem2>();
    static int mCurItemIdCount = 0;
    RectTransform mItemParent = null;
    public ItemPool()
    {
       
    }
    public void Init(GameObject prefabObj, float padding,float startPosOffset, int createCount, RectTransform parent)
    {
        mPrefabObj = prefabObj;
        mPrefabName = mPrefabObj.name;
        mInitCreateCount = createCount;
        mPadding = padding;
        mStartPosOffset = startPosOffset;
        mItemParent = parent;
        mPrefabObj.SetActive(false);
        for (int i = 0; i < mInitCreateCount; ++i)
        {
            LoopListViewItem2 tViewItem = CreateItem();
            RecycleItemReal(tViewItem);
        }
    }
    public LoopListViewItem2 GetItem()
    {
        mCurItemIdCount++;
        LoopListViewItem2 tItem = null;
        if(mTmpPooledItemList.Count > 0)
        {
            int count = mTmpPooledItemList.Count;
            tItem = mTmpPooledItemList[count - 1];
            mTmpPooledItemList.RemoveAt(count - 1);
            tItem.gameObject.SetActive(true);
        }
        else
        {
            int count = mPooledItemList.Count;
            if (count == 0)
            {
                tItem = CreateItem();
            }
            else
            {
                tItem = mPooledItemList[count - 1];
                mPooledItemList.RemoveAt(count - 1);
                tItem.gameObject.SetActive(true);
            }
        }
        tItem.Padding = mPadding;
        tItem.ItemId = mCurItemIdCount;
        return tItem;

    }

    public void DestroyAllItem()
    {
        ClearTmpRecycledItem();
        int count = mPooledItemList.Count;
        for (int i = 0;i<count;++i)
        {
            GameObject.DestroyImmediate(mPooledItemList[i].gameObject);
        }
        mPooledItemList.Clear();
    }
    public LoopListViewItem2 CreateItem()
    {

        GameObject go = GameObject.Instantiate<GameObject>(mPrefabObj, Vector3.zero,Quaternion.identity, mItemParent);
        go.SetActive(true);
        RectTransform rf = go.GetComponent<RectTransform>();
        rf.localScale = Vector3.one;
        rf.localPosition = Vector3.zero;
        rf.localEulerAngles = Vector3.zero;
        LoopListViewItem2 tViewItem = go.GetComponent<LoopListViewItem2>();
        tViewItem.ItemPrefabName = mPrefabName;
        tViewItem.StartPosOffset = mStartPosOffset;
        return tViewItem;
    }
    void RecycleItemReal(LoopListViewItem2 item)
    {
        item.gameObject.SetActive(false);
        mPooledItemList.Add(item);
    }
    public void RecycleItem(LoopListViewItem2 item)
    {
        mTmpPooledItemList.Add(item);
    }
    public void ClearTmpRecycledItem()
    {
        int count = mTmpPooledItemList.Count;
        if(count == 0)
        {
            return;
        }
        for(int i = 0;i<count;++i)
        {
            RecycleItemReal(mTmpPooledItemList[i]);
        }
        mTmpPooledItemList.Clear();
    }
}
[System.Serializable]
public class ItemPrefabConfData
{
    public GameObject mItemPrefab = null;
    public float mPadding = 0;
    public int mInitCreateCount = 0;
    public float mStartPosOffset = 0;
}


public class LoopListViewInitParam
{
    // all the default values
    public float mDistanceForRecycle0 = 300; //mDistanceForRecycle0 should be larger than mDistanceForNew0
    public float mDistanceForNew0 = 200;
    public float mDistanceForRecycle1 = 300;//mDistanceForRecycle1 should be larger than mDistanceForNew1
    public float mDistanceForNew1 = 200;
    public float mSmoothDumpRate = 0.3f;
    public float mSnapFinishThreshold = 0.01f;
    public float mSnapVecThreshold = 145;
    public float mItemDefaultWithPaddingSize = 20;

    public static LoopListViewInitParam CopyDefaultInitParam()
    {
        return new LoopListViewInitParam();
    }
}

public enum SnapStatus
{
    NoTargetSet = 0,
    TargetHasSet = 1,
    SnapMoving = 2,
    SnapMoveFinish = 3
}



public class LoopListView2 : MonoBehaviour, IBeginDragHandler, IEndDragHandler, IDragHandler
{

    class SnapData
    {
        public SnapStatus mSnapStatus = SnapStatus.NoTargetSet;
        public int mSnapTargetIndex = 0;
        public float mTargetSnapVal = 0;
        public float mCurSnapVal = 0;
        public void Clear()
        {
            mSnapStatus = SnapStatus.NoTargetSet;
        }
    }

    Dictionary<string, ItemPool> mItemPoolDict = new Dictionary<string, ItemPool>();
    List<ItemPool> mItemPoolList = new List<ItemPool>();
    [SerializeField]
    List<ItemPrefabConfData> mItemPrefabDataList = new List<ItemPrefabConfData>();

    [SerializeField]
    private ListItemArrangeType mArrangeType = ListItemArrangeType.TopToBottom;
    public ListItemArrangeType ArrangeType { get { return mArrangeType; } set { mArrangeType = value; } }

    List<LoopListViewItem2> mItemList = new List<LoopListViewItem2>();
    RectTransform mContainerTrans;
    ScrollRect mScrollRect = null;
    RectTransform mScrollRectTransform = null;
    RectTransform mViewPortRectTransform = null;
    float mItemDefaultWithPaddingSize = 20;
    int mItemTotalCount = 0;
    bool mIsVertList = false;
    System.Func<LoopListView2, int, LoopListViewItem2> mOnGetItemByIndex;
    Vector3[] mItemWorldCorners = new Vector3[4];
    Vector3[] mViewPortRectLocalCorners = new Vector3[4];
    int mCurReadyMinItemIndex = 0;
    int mCurReadyMaxItemIndex = 0;
    bool mNeedCheckNextMinItem = true;
    bool mNeedCheckNextMaxItem = true;
    ItemPosMgr mItemPosMgr = null;
    float mDistanceForRecycle0 = 300;
    float mDistanceForNew0 = 200;
    float mDistanceForRecycle1 = 300;
    float mDistanceForNew1 = 200;
    [SerializeField]
    bool mSupportScrollBar = true;
    bool mIsDraging = false;
    PointerEventData mPointerEventData = null;
    public System.Action mOnBeginDragAction = null;
    public System.Action mOnDragingAction = null;
    public System.Action mOnEndDragAction = null;
    int mLastItemIndex = 0;
    float mLastItemPadding = 0;
    float mSmoothDumpVel = 0;
    float mSmoothDumpRate = 0.3f;
    float mSnapFinishThreshold = 0.1f;
    float mSnapVecThreshold = 145;
    [SerializeField]
    bool mItemSnapEnable = false;


    Vector3 mLastFrameContainerPos = Vector3.zero;
    public System.Action<LoopListView2,LoopListViewItem2> mOnSnapItemFinished = null;
    public System.Action<LoopListView2, LoopListViewItem2> mOnSnapNearestChanged = null;
    int mCurSnapNearestItemIndex = -1;
    Vector2 mAdjustedVec;
    bool mNeedAdjustVec = false;
    int mLeftSnapUpdateExtraCount = 1;
    [SerializeField]
    Vector2 mViewPortSnapPivot = Vector2.zero;
    [SerializeField]
    Vector2 mItemSnapPivot = Vector2.zero;
    ClickEventListener mScrollBarClickEventListener = null;
    SnapData mCurSnapData = new SnapData();
    Vector3 mLastSnapCheckPos = Vector3.zero;
    bool mListViewInited = false;
    int mListUpdateCheckFrameCount = 0;
    public bool IsVertList
    {
        get
        {
            return mIsVertList;
        }
    }
    public int ItemTotalCount
    {
        get
        {
            return mItemTotalCount;
        }
    }

    public RectTransform ContainerTrans
    {
        get
        {
            return mContainerTrans;
        }
    }

    public ScrollRect ScrollRect
    {
        get
        {
            return mScrollRect;
        }
    }

    public bool IsDraging
    {
        get
        {
            return mIsDraging;
        }
    }

    public bool ItemSnapEnable
    {
        get {return mItemSnapEnable;}
        set { mItemSnapEnable = value; }
    }

    public bool SupportScrollBar
    {
        get { return mSupportScrollBar; }
        set { mSupportScrollBar = value; }
    }

    public ItemPrefabConfData GetItemPrefabConfData(string prefabName)
    {
        foreach (ItemPrefabConfData data in mItemPrefabDataList)
        {
            if (data.mItemPrefab == null)
            {
                Debug.LogError("A item prefab is null ");
                continue;
            }
            if (prefabName == data.mItemPrefab.name)
            {
                return data;
            }

        }
        return null;
    }

    public void OnItemPrefabChanged(string prefabName)
    {
        ItemPrefabConfData data = GetItemPrefabConfData(prefabName);
        if(data == null)
        {
            return;
        }
        ItemPool pool = null;
        if (mItemPoolDict.TryGetValue(prefabName, out pool) == false)
        {
            return;
        }
        int firstItemIndex = -1;
        Vector3 pos = Vector3.zero;
        if(mItemList.Count > 0)
        {
            firstItemIndex = mItemList[0].ItemIndex;
            pos = mItemList[0].CachedRectTransform.localPosition;
        }
        RecycleAllItem();
        ClearAllTmpRecycledItem();
        pool.DestroyAllItem();
        pool.Init(data.mItemPrefab, data.mPadding, data.mStartPosOffset,data.mInitCreateCount, mContainerTrans);
        if(firstItemIndex >= 0)
        {
            RefreshAllShownItemWithFirstIndexAndPos(firstItemIndex, pos);
        }
    }

    /*
    InitListView method is to initiate the LoopListView2 component. There are 3 parameters:
    itemTotalCount: the total item count in the listview. If this parameter is set -1, then means there are infinite items, and scrollbar would not be supported, and the ItemIndex can be from –MaxInt to +MaxInt. If this parameter is set a value >=0 , then the ItemIndex can only be from 0 to itemTotalCount -1.
    onGetItemByIndex: when a item is getting in the scrollrect viewport, and this Action will be called with the item’ index as a parameter, to let you create the item and update its content.
    
         InitListView方法是启动LoopListView2组件。有三个参数:itemTotalCount:listview中的项目总数。如果该参数设置为- 1,则意味着有无限项,而滚动条不受支持,ItemIndex可以从- MaxInt到+ MaxInt。如果该参数设置值> = 0,则ItemIndex只能从0到itemTotalCount - 1。onGetItemByIndex:当一个条目进入scrollrect viewport时,这个动作将被称为“index作为参数”,让您创建条目并更新它的内容*/
    public void InitListView(int itemTotalCount,
        System.Func<LoopListView2, int, LoopListViewItem2> onGetItemByIndex,
        LoopListViewInitParam initParam = null)
    {
        if(initParam != null)
        {
            mDistanceForRecycle0 = initParam.mDistanceForRecycle0;
            mDistanceForNew0 = initParam.mDistanceForNew0;
            mDistanceForRecycle1 = initParam.mDistanceForRecycle1;
            mDistanceForNew1 = initParam.mDistanceForNew1;
            mSmoothDumpRate = initParam.mSmoothDumpRate;
            mSnapFinishThreshold = initParam.mSnapFinishThreshold;
            mSnapVecThreshold = initParam.mSnapVecThreshold;
            mItemDefaultWithPaddingSize = initParam.mItemDefaultWithPaddingSize;
        }
        mScrollRect = gameObject.GetComponent<ScrollRect>();
        if (mScrollRect == null)
        {
            Debug.LogError("ListView Init Failed! ScrollRect component not found!");
            return;
        }
        if(mDistanceForRecycle0 <= mDistanceForNew0)
        {
            Debug.LogError("mDistanceForRecycle0 should be bigger than mDistanceForNew0");
        }
        if (mDistanceForRecycle1 <= mDistanceForNew1)
        {
            Debug.LogError("mDistanceForRecycle1 should be bigger than mDistanceForNew1");
        }
        mCurSnapData.Clear();
        mItemPosMgr = new ItemPosMgr(mItemDefaultWithPaddingSize);
        mScrollRectTransform = mScrollRect.GetComponent<RectTransform>();
        mContainerTrans = mScrollRect.content;
        mViewPortRectTransform = mScrollRect.viewport;
        if (mViewPortRectTransform == null)
        {
            mViewPortRectTransform = mScrollRectTransform;
        }
        if (mScrollRect.horizontalScrollbarVisibility == ScrollRect.ScrollbarVisibility.AutoHideAndExpandViewport && mScrollRect.horizontalScrollbar != null)
        {
            Debug.LogError("ScrollRect.horizontalScrollbarVisibility cannot be set to AutoHideAndExpandViewport");
        }
        if (mScrollRect.verticalScrollbarVisibility == ScrollRect.ScrollbarVisibility.AutoHideAndExpandViewport && mScrollRect.verticalScrollbar != null)
        {
            Debug.LogError("ScrollRect.verticalScrollbarVisibility cannot be set to AutoHideAndExpandViewport");
        }
        mIsVertList = (mArrangeType == ListItemArrangeType.TopToBottom || mArrangeType == ListItemArrangeType.BottomToTop);
        mScrollRect.horizontal = !mIsVertList;
        mScrollRect.vertical = mIsVertList;
        SetScrollbarListener();
        AdjustPivot(mViewPortRectTransform);
        AdjustAnchor(mContainerTrans);
        AdjustContainerPivot(mContainerTrans);
        InitItemPool();
        mOnGetItemByIndex = onGetItemByIndex;
        if(mListViewInited == true)
        {
            Debug.LogError("LoopListView2.InitListView method can be called only once.");
        }
        mListViewInited = true;
        ResetListView();
        SetListItemCount(itemTotalCount, true);
    }

    void SetScrollbarListener()
    {
        mScrollBarClickEventListener = null;
        Scrollbar curScrollBar = null;
        if (mIsVertList && mScrollRect.verticalScrollbar != null)
        {
            curScrollBar = mScrollRect.verticalScrollbar;

        }
        if (!mIsVertList && mScrollRect.horizontalScrollbar != null)
        {
            curScrollBar = mScrollRect.horizontalScrollbar;
        }
        if(curScrollBar == null)
        {
            return;
        }
        ClickEventListener listener = ClickEventListener.Get(curScrollBar.gameObject);
        mScrollBarClickEventListener = listener;
        listener.SetPointerUpHandler(OnPointerUpInScrollBar);
        listener.SetPointerDownHandler(OnPointerDownInScrollBar);
    }

    void OnPointerDownInScrollBar(GameObject obj)
    {
        mCurSnapData.Clear();
    }

    void OnPointerUpInScrollBar(GameObject obj)
    {
        ForceSnapUpdateCheck();
    }

    public void ResetListView()
    {
        mViewPortRectTransform.GetLocalCorners(mViewPortRectLocalCorners);
        mContainerTrans.localPosition = Vector3.zero;
        ForceSnapUpdateCheck();
    }


    /*
    This method may use to set the item total count of the scrollview at runtime. 
    If this parameter is set -1, then means there are infinite items,
    and scrollbar would not be supported, and the ItemIndex can be from –MaxInt to +MaxInt. 
    If this parameter is set a value >=0 , then the ItemIndex can only be from 0 to itemTotalCount -1.  
    If resetPos is set false, then the scrollrect’s content position will not changed after this method finished.
    此方法可用于在运行时设置scrollview的项目总数。如果这个参数是- 1,那么就意味着有无穷项,滚动条不支持,ItemIndex可以从- MaxInt到+ MaxInt。如果该参数设置值> = 0,则ItemIndex只能从0到itemTotalCount - 1。 如果resetPos设置为false,则在此方法完成后,scrollrect的内容位置将不会改变。
    */
    public void SetListItemCount(int itemCount, bool resetPos = true)
    {
        if(itemCount == mItemTotalCount)
        {
            return;
        }
        mCurSnapData.Clear();
        mItemTotalCount = itemCount;
        if (mItemTotalCount < 0)
        {
            mSupportScrollBar = false;
        }
        if (mSupportScrollBar)
        {
            mItemPosMgr.SetItemMaxCount(mItemTotalCount);
        }
        else
        {
            mItemPosMgr.SetItemMaxCount(0);
        }
        if (mItemTotalCount == 0)
        {
            mCurReadyMaxItemIndex = 0;
            mCurReadyMinItemIndex = 0;
            mNeedCheckNextMaxItem = false;
            mNeedCheckNextMinItem = false;
            RecycleAllItem();
            ClearAllTmpRecycledItem();
            UpdateContentSize();
            return;
        }
        mLeftSnapUpdateExtraCount = 1;
        mNeedCheckNextMaxItem = true;
        mNeedCheckNextMinItem = true;
        if (resetPos)
        {
            MovePanelToItemIndex(0, 0);
            return;
        }
        if (mItemList.Count == 0)
        {
            MovePanelToItemIndex(0, 0);
            return;
        }
        int maxItemIndex = mItemTotalCount - 1;
        int lastItemIndex = mItemList[mItemList.Count - 1].ItemIndex;
        if (lastItemIndex <= maxItemIndex)
        {
            UpdateContentSize();
            UpdateAllShownItemsPos();
            return;
        }
        MovePanelToItemIndex(maxItemIndex, 0);

    }

    //To get the visible item by itemIndex. If the item is not visible, then this method return null.
    //通过itemIndex获取可见项。如果该项不可见,则此方法返回null。
    public LoopListViewItem2 GetShownItemByItemIndex(int itemIndex)
    {
        int count = mItemList.Count;
       // Debug.Log("mItemList[count - 1].ItemIndex :" + mItemList[count - 1].ItemIndex);
        if (count == 0)
        {
            return null;
        }
        if (itemIndex < mItemList[0].ItemIndex || itemIndex > mItemList[count - 1].ItemIndex)
        {
            return null;
        }
        int i = itemIndex - mItemList[0].ItemIndex;
        return mItemList[i];
    }

    public int ShownItemCount
    {
        get
        {
            return mItemList.Count;
        }
    }

    public float ViewPortSize
    {
        get
        {
            if (mIsVertList)
            {
                return mViewPortRectTransform.rect.height;
            }
            else
            {
                return mViewPortRectTransform.rect.width;
            }
        }
    }

    public float ViewPortWidth
    {
        get { return mViewPortRectTransform.rect.width; }
    }
    public float ViewPortHeight
    {
        get { return mViewPortRectTransform.rect.height; }
    }


    /*
     All visible items is stored in a List<LoopListViewItem2> , which is named mItemList;
     this method is to get the visible item by the index in visible items list. The parameter index is from 0 to mItemList.Count.
     所有可见项都存储在一个列表<LoopListViewItem2>中,它被命名为mItemList;这个方法是通过在可见项列表中的索引获取可见项。参数索引是从0到mItemList.Count。
    */
    public LoopListViewItem2 GetShownItemByIndex(int index)
    {
        int count = mItemList.Count;
        if(index < 0 || index >= count)
        {
            return null;
        }
        return mItemList[index];
    }

    public LoopListViewItem2 GetShownItemByIndexWithoutCheck(int index)
    {
        return mItemList[index];
    }

    public int GetIndexInShownItemList(LoopListViewItem2 item)
    {
        if(item == null)
        {
            return -1;
        }
        int count = mItemList.Count;
        if (count == 0)
        {
            return -1;
        }
        for (int i = 0; i < count; ++i)
        {
            if (mItemList[i] == item)
            {
                return i;
            }
        }
        return -1;
    }


    public void DoActionForEachShownItem(System.Action<LoopListViewItem2,object> action,object param)
    {
        if(action == null)
        {
            return;
        }
        int count = mItemList.Count;
        if(count == 0)
        {
            return;
        }
        for (int i = 0; i < count; ++i)
        {
            action(mItemList[i],param);
        }
    }


    public LoopListViewItem2 NewListViewItem(string itemPrefabName)
    {
        ItemPool pool = null;
        if (mItemPoolDict.TryGetValue(itemPrefabName, out pool) == false)
        {
            
            return null;
        }
        LoopListViewItem2 item = pool.GetItem();
        RectTransform rf = item.GetComponent<RectTransform>();
        rf.SetParent(mContainerTrans);
        rf.localScale = Vector3.one;
        rf.localPosition = Vector3.zero;
        rf.localEulerAngles = Vector3.zero;
        item.ParentListView = this;
        return item;
    }

    /*
    For a vertical scrollrect, when a visible item’s height changed at runtime, then this method should be called to let the LoopListView2 component reposition all visible items’ position.
    For a horizontal scrollrect, when a visible item’s width changed at runtime, then this method should be called to let the LoopListView2 component reposition all visible items’ position.
   对于垂直scrollrect,当一个可见项的高度在运行时发生变化时,应该调用该方法来让LoopListView2组件重新定位所有可见项的位置。对于水平scrollrect,当一个可见项的宽度在运行时发生变化时,应该调用这个方法,让LoopListView2组件重新定位所有可见项的位置。 */
    public void OnItemSizeChanged(int itemIndex)
    {
        LoopListViewItem2 item = GetShownItemByItemIndex(itemIndex);
        if (item == null)
        {
            return;
        }
        if (mSupportScrollBar)
        {
            if (mIsVertList)
            {
                SetItemSize(itemIndex, item.CachedRectTransform.rect.height, item.Padding);
            }
            else
            {
                SetItemSize(itemIndex, item.CachedRectTransform.rect.width, item.Padding);
            }
        }
        UpdateContentSize();
        UpdateAllShownItemsPos();
    }


    /*
    To update a item by itemIndex.if the itemIndex-th item is not visible, then this method will do nothing.
    Otherwise this method will first call onGetItemByIndex(itemIndex) to get a updated item and then reposition all visible items'position. 
    按项目索引更新项目。如果不可见itemindex - th项,则此方法将不做任何事情。否则,该方法将首先调用onGetItemByIndex(itemIndex)来获取更新后的项目,然后重新定位所有可见项的位置。
    */
    public void RefreshItemByItemIndex(int itemIndex)
    {
        int count = mItemList.Count;
        if (count == 0)
        {
            return;
        }
        if (itemIndex < mItemList[0].ItemIndex || itemIndex > mItemList[count - 1].ItemIndex)
        {
            return;
        }
        int firstItemIndex = mItemList[0].ItemIndex;
        int i = itemIndex - firstItemIndex;
        LoopListViewItem2 curItem = mItemList[i];
        Vector3 pos = curItem.CachedRectTransform.localPosition;
        RecycleItemTmp(curItem);
        LoopListViewItem2 newItem = GetNewItemByIndex(itemIndex);
        if (newItem == null)
        {
            RefreshAllShownItemWithFirstIndex(firstItemIndex);
            return;
        }
        mItemList[i] = newItem;
        if(mIsVertList)
        {
            pos.x = newItem.StartPosOffset;
        }
        else
        {
            pos.y = newItem.StartPosOffset;
        }
        newItem.CachedRectTransform.localPosition = pos;
        OnItemSizeChanged(itemIndex);
        ClearAllTmpRecycledItem();
    }

    //snap move will finish at once.
    public void FinishSnapImmediately()
    {
        UpdateSnapMove(true);
    }

    /*
    This method will move the scrollrect content’s position to ( the positon of itemIndex-th item + offset ),
    and in current version the itemIndex is from 0 to MaxInt, offset is from 0 to scrollrect viewport size. 
    该方法将把scrollrect内容的位置移动到(itemindex - th项+偏移量的positon),在当前版本中,itemIndex从0到MaxInt,偏移量从0到scrollrect viewport大小。*/
    public void MovePanelToItemIndex(int itemIndex, float offset)
    {
        mScrollRect.StopMovement();
        mCurSnapData.Clear();
        if (itemIndex < 0 || mItemTotalCount == 0)
        {
            return;
        }
        if (mItemTotalCount > 0 && itemIndex >= mItemTotalCount)
        {
            itemIndex = mItemTotalCount - 1;
        }
        if (offset < 0)
        {
            offset = 0;
        }
        Vector3 pos = Vector3.zero;
        float viewPortSize = ViewPortSize;
        if (offset > viewPortSize)
        {
            offset = viewPortSize;
        }
        if (mArrangeType == ListItemArrangeType.TopToBottom)
        {
            float containerPos = mContainerTrans.localPosition.y;
            if (containerPos < 0)
            {
                containerPos = 0;
            }
            pos.y = -containerPos - offset;
        }
        else if (mArrangeType == ListItemArrangeType.BottomToTop)
        {
            float containerPos = mContainerTrans.localPosition.y;
            if (containerPos > 0)
            {
                containerPos = 0;
            }
            pos.y = -containerPos + offset;
        }
        else if (mArrangeType == ListItemArrangeType.LeftToRight)
        {
            float containerPos = mContainerTrans.localPosition.x;
            if (containerPos > 0)
            {
                containerPos = 0;
            }
            pos.x = -containerPos + offset;
        }
        else if (mArrangeType == ListItemArrangeType.RightToLeft)
        {
            float containerPos = mContainerTrans.localPosition.x;
            if (containerPos < 0)
            {
                containerPos = 0;
            }
            pos.x = -containerPos - offset;
        }

        RecycleAllItem();
        LoopListViewItem2 newItem = GetNewItemByIndex(itemIndex);
        if (newItem == null)
        {
            ClearAllTmpRecycledItem();
            return;
        }
        if (mIsVertList)
        {
            pos.x = newItem.StartPosOffset;
        }
        else
        {
            pos.y = newItem.StartPosOffset;
        }
        newItem.CachedRectTransform.localPosition = pos;
        if (mSupportScrollBar)
        {
            if (mIsVertList)
            {
                SetItemSize(itemIndex, newItem.CachedRectTransform.rect.height, newItem.Padding);
            }
            else
            {
                SetItemSize(itemIndex, newItem.CachedRectTransform.rect.width, newItem.Padding);
            }
        }
        mItemList.Add(newItem);
        UpdateContentSize();
        UpdateListView(viewPortSize + 100, viewPortSize + 100, viewPortSize, viewPortSize);
        AdjustPanelPos();
        ClearAllTmpRecycledItem();
    }

    //update all visible items.
    //更新所有可见的物品。
    public void RefreshAllShownItem()
    {
        int count = mItemList.Count;
        if (count == 0)
        {
            return;
        }
        RefreshAllShownItemWithFirstIndex(mItemList[0].ItemIndex);
    }


    public void RefreshAllShownItemWithFirstIndex(int firstItemIndex)
    {
        int count = mItemList.Count;
        if (count == 0)
        {
            return;
        }
        LoopListViewItem2 firstItem = mItemList[0];
        Vector3 pos = firstItem.CachedRectTransform.localPosition;
        RecycleAllItem();
        for (int i = 0; i < count; ++i)
        {
            int curIndex = firstItemIndex + i;
            LoopListViewItem2 newItem = GetNewItemByIndex(curIndex);
            if (newItem == null)
            {
                break;
            }
            if (mIsVertList)
            {
                pos.x = newItem.StartPosOffset;
            }
            else
            {
                pos.y = newItem.StartPosOffset;
            }
            newItem.CachedRectTransform.localPosition = pos;
            if (mSupportScrollBar)
            {
                if (mIsVertList)
                {
                    SetItemSize(curIndex, newItem.CachedRectTransform.rect.height, newItem.Padding);
                }
                else
                {
                    SetItemSize(curIndex, newItem.CachedRectTransform.rect.width, newItem.Padding);
                }
            }

            mItemList.Add(newItem);
        }
        UpdateContentSize();
        UpdateAllShownItemsPos();
        ClearAllTmpRecycledItem();
    }


    public void RefreshAllShownItemWithFirstIndexAndPos(int firstItemIndex,Vector3 pos)
    {
        RecycleAllItem();
        LoopListViewItem2 newItem = GetNewItemByIndex(firstItemIndex);
        if (newItem == null)
        {
            return;
        }
        if (mIsVertList)
        {
            pos.x = newItem.StartPosOffset;
        }
        else
        {
            pos.y = newItem.StartPosOffset;
        }
        newItem.CachedRectTransform.localPosition = pos;
        if (mSupportScrollBar)
        {
            if (mIsVertList)
            {
                SetItemSize(firstItemIndex, newItem.CachedRectTransform.rect.height, newItem.Padding);
            }
            else
            {
                SetItemSize(firstItemIndex, newItem.CachedRectTransform.rect.width, newItem.Padding);
            }
        }
        mItemList.Add(newItem);
        UpdateContentSize();
        UpdateAllShownItemsPos();
        UpdateListView(mDistanceForRecycle0, mDistanceForRecycle1, mDistanceForNew0, mDistanceForNew1);
        ClearAllTmpRecycledItem();
    }


    void RecycleItemTmp(LoopListViewItem2 item)
    {
        if (item == null)
        {
            return;
        }
        if (string.IsNullOrEmpty(item.ItemPrefabName))
        {
            return;
        }
        ItemPool pool = null;
        if (mItemPoolDict.TryGetValue(item.ItemPrefabName, out pool) == false)
        {
            return;
        }
        pool.RecycleItem(item);

    }


    public void ClearAllTmpRecycledItem()
    {
        int count = mItemPoolList.Count;
        for(int i = 0;i<count;++i)
        {
            mItemPoolList[i].ClearTmpRecycledItem();
        }
    }


    public void RecycleAllItem()
    {
        foreach (LoopListViewItem2 item in mItemList)
        {
            RecycleItemTmp(item);
        }
        mItemList.Clear();
    }


    void AdjustContainerPivot(RectTransform rtf)
    {
        Vector2 pivot = rtf.pivot;
        if (mArrangeType == ListItemArrangeType.BottomToTop)
        {
            pivot.y = 0;
        }
        else if (mArrangeType == ListItemArrangeType.TopToBottom)
        {
            pivot.y = 1;
        }
        else if (mArrangeType == ListItemArrangeType.LeftToRight)
        {
            pivot.x = 0;
        }
        else if (mArrangeType == ListItemArrangeType.RightToLeft)
        {
            pivot.x = 1;
        }
        rtf.pivot = pivot;
    }


    void AdjustPivot(RectTransform rtf)
    {
        Vector2 pivot = rtf.pivot;

        if (mArrangeType == ListItemArrangeType.BottomToTop)
        {
            pivot.y = 0;
        }
        else if (mArrangeType == ListItemArrangeType.TopToBottom)
        {
            pivot.y = 1;
        }
        else if (mArrangeType == ListItemArrangeType.LeftToRight)
        {
            pivot.x = 0;
        }
        else if (mArrangeType == ListItemArrangeType.RightToLeft)
        {
            pivot.x = 1;
        }
        rtf.pivot = pivot;
    }

    void AdjustContainerAnchor(RectTransform rtf)
    {
        Vector2 anchorMin = rtf.anchorMin;
        Vector2 anchorMax = rtf.anchorMax;
        if (mArrangeType == ListItemArrangeType.BottomToTop)
        {
            anchorMin.y = 0;
            anchorMax.y = 0;
        }
        else if (mArrangeType == ListItemArrangeType.TopToBottom)
        {
            anchorMin.y = 1;
            anchorMax.y = 1;
        }
        else if (mArrangeType == ListItemArrangeType.LeftToRight)
        {
            anchorMin.x = 0;
            anchorMax.x = 0;
        }
        else if (mArrangeType == ListItemArrangeType.RightToLeft)
        {
            anchorMin.x = 1;
            anchorMax.x = 1;
        }
        rtf.anchorMin = anchorMin;
        rtf.anchorMax = anchorMax;
    }


    void AdjustAnchor(RectTransform rtf)
    {
        Vector2 anchorMin = rtf.anchorMin;
        Vector2 anchorMax = rtf.anchorMax;
        if (mArrangeType == ListItemArrangeType.BottomToTop)
        {
            anchorMin.y = 0;
            anchorMax.y = 0;
        }
        else if (mArrangeType == ListItemArrangeType.TopToBottom)
        {
            anchorMin.y = 1;
            anchorMax.y = 1;
        }
        else if (mArrangeType == ListItemArrangeType.LeftToRight)
        {
            anchorMin.x = 0;
            anchorMax.x = 0;
        }
        else if (mArrangeType == ListItemArrangeType.RightToLeft)
        {
            anchorMin.x = 1;
            anchorMax.x = 1;
        }
        rtf.anchorMin = anchorMin;
        rtf.anchorMax = anchorMax;
    }

    void InitItemPool()
    {
        foreach (ItemPrefabConfData data in mItemPrefabDataList)
        {
            if (data.mItemPrefab == null)
            {
                Debug.LogError("A item prefab is null ");
                continue;
            }
            string prefabName = data.mItemPrefab.name;
            if (mItemPoolDict.ContainsKey(prefabName))
            {
                Debug.LogError("A item prefab with name " + prefabName + " has existed!");
                continue;
            }
            RectTransform rtf = data.mItemPrefab.GetComponent<RectTransform>();
            if (rtf == null)
            {
                Debug.LogError("RectTransform component is not found in the prefab " + prefabName);
                continue;
            }
            AdjustAnchor(rtf);
            AdjustPivot(rtf);
            LoopListViewItem2 tItem = data.mItemPrefab.GetComponent<LoopListViewItem2>();
            if (tItem == null)
            {
                data.mItemPrefab.AddComponent<LoopListViewItem2>();
            }
            ItemPool pool = new ItemPool();
            pool.Init(data.mItemPrefab, data.mPadding,data.mStartPosOffset, data.mInitCreateCount, mContainerTrans);
            mItemPoolDict.Add(prefabName, pool);
            mItemPoolList.Add(pool);
        }
    }



    public virtual void OnBeginDrag(PointerEventData eventData)
    {
        if (eventData.button != PointerEventData.InputButton.Left)
        {
            return;
        }
        mIsDraging = true;
        CacheDragPointerEventData(eventData);
        mCurSnapData.Clear();
        if(mOnBeginDragAction != null)
        {
            mOnBeginDragAction();
        }
    }

    public virtual void OnEndDrag(PointerEventData eventData)
    {
        if (eventData.button != PointerEventData.InputButton.Left)
        {
            return;
        }
        mIsDraging = false;
        mPointerEventData = null;
        if (mOnEndDragAction != null)
        {
            mOnEndDragAction();
        }
        ForceSnapUpdateCheck();
    }

    public virtual void OnDrag(PointerEventData eventData)
    {
        if (eventData.button != PointerEventData.InputButton.Left)
        {
            return;
        }
        CacheDragPointerEventData(eventData);
        if (mOnDragingAction != null)
        {
            mOnDragingAction();
        }
    }

    void CacheDragPointerEventData(PointerEventData eventData)
    {
        if (mPointerEventData == null)
        {
            mPointerEventData = new PointerEventData(EventSystem.current);
        }
        mPointerEventData.button = eventData.button;
        mPointerEventData.position = eventData.position;
        mPointerEventData.pointerPressRaycast = eventData.pointerPressRaycast;
        mPointerEventData.pointerCurrentRaycast = eventData.pointerCurrentRaycast;
    }

    LoopListViewItem2 GetNewItemByIndex(int index)
    {
        if(mSupportScrollBar && index < 0)
        {
            return null;
        }
        if(mItemTotalCount > 0 && index >= mItemTotalCount)
        {
            return null;
        }
        LoopListViewItem2 newItem = mOnGetItemByIndex(this, index);
        if (newItem == null)
        {
            return null;
        }
        newItem.ItemIndex = index;
        newItem.ItemCreatedCheckFrameCount = mListUpdateCheckFrameCount;
        return newItem;
    }


    void SetItemSize(int itemIndex, float itemSize,float padding)
    {
        mItemPosMgr.SetItemSize(itemIndex, itemSize+padding);
        if(itemIndex >= mLastItemIndex)
        {
            mLastItemIndex = itemIndex;
            mLastItemPadding = padding;
        }
    }

    void GetPlusItemIndexAndPosAtGivenPos(float pos, ref int index, ref float itemPos)
    {
        mItemPosMgr.GetItemIndexAndPosAtGivenPos(pos, ref index, ref itemPos);
    }


    float GetItemPos(int itemIndex)
    {
        return mItemPosMgr.GetItemPos(itemIndex);
    }

  
    public Vector3 GetItemCornerPosInViewPort(LoopListViewItem2 item, ItemCornerEnum corner = ItemCornerEnum.LeftBottom)
    {
        item.CachedRectTransform.GetWorldCorners(mItemWorldCorners);
        return mViewPortRectTransform.InverseTransformPoint(mItemWorldCorners[(int)corner]);
    }
   

    void AdjustPanelPos()
    {
        int count = mItemList.Count;
        if (count == 0)
        {
            return;
        }
        UpdateAllShownItemsPos();
        float viewPortSize = ViewPortSize;
        float contentSize = GetContentPanelSize();
        if (mArrangeType == ListItemArrangeType.TopToBottom)
        {
            if (contentSize <= viewPortSize)
            {
                Vector3 pos = mContainerTrans.localPosition;
                pos.y = 0;
                mContainerTrans.localPosition = pos;
                mItemList[0].CachedRectTransform.localPosition = new Vector3(mItemList[0].StartPosOffset,0,0);
                UpdateAllShownItemsPos();
                return;
            }
            LoopListViewItem2 tViewItem0 = mItemList[0];
            tViewItem0.CachedRectTransform.GetWorldCorners(mItemWorldCorners);
            Vector3 topPos0 = mViewPortRectTransform.InverseTransformPoint(mItemWorldCorners[1]);
            if (topPos0.y < mViewPortRectLocalCorners[1].y)
            {
                Vector3 pos = mContainerTrans.localPosition;
                pos.y = 0;
                mContainerTrans.localPosition = pos;
                mItemList[0].CachedRectTransform.localPosition = new Vector3(mItemList[0].StartPosOffset, 0, 0);
                UpdateAllShownItemsPos();
                return;
            }
            LoopListViewItem2 tViewItem1 = mItemList[mItemList.Count - 1];
            tViewItem1.CachedRectTransform.GetWorldCorners(mItemWorldCorners);
            Vector3 downPos1 = mViewPortRectTransform.InverseTransformPoint(mItemWorldCorners[0]);
            float d = downPos1.y - mViewPortRectLocalCorners[0].y;
            if (d > 0)
            {
                Vector3 pos = mItemList[0].CachedRectTransform.localPosition;
                pos.y = pos.y - d;
                mItemList[0].CachedRectTransform.localPosition = pos;
                UpdateAllShownItemsPos();
                return;
            }
        }
        else if (mArrangeType == ListItemArrangeType.BottomToTop)
        {
            if (contentSize <= viewPortSize)
            {
                Vector3 pos = mContainerTrans.localPosition;
                pos.y = 0;
                mContainerTrans.localPosition = pos;
                mItemList[0].CachedRectTransform.localPosition = new Vector3(mItemList[0].StartPosOffset, 0, 0);
                UpdateAllShownItemsPos();
                return;
            }
            LoopListViewItem2 tViewItem0 = mItemList[0];
            tViewItem0.CachedRectTransform.GetWorldCorners(mItemWorldCorners);
            Vector3 downPos0 = mViewPortRectTransform.InverseTransformPoint(mItemWorldCorners[0]);
            if (downPos0.y > mViewPortRectLocalCorners[0].y)
            {
                Vector3 pos = mContainerTrans.localPosition;
                pos.y = 0;
                mContainerTrans.localPosition = pos;
                mItemList[0].CachedRectTransform.localPosition = new Vector3(mItemList[0].StartPosOffset, 0, 0);
                UpdateAllShownItemsPos();
                return;
            }
            LoopListViewItem2 tViewItem1 = mItemList[mItemList.Count - 1];
            tViewItem1.CachedRectTransform.GetWorldCorners(mItemWorldCorners);
            Vector3 topPos1 = mViewPortRectTransform.InverseTransformPoint(mItemWorldCorners[1]);
            float d = mViewPortRectLocalCorners[1].y - topPos1.y;
            if (d > 0)
            {
                Vector3 pos = mItemList[0].CachedRectTransform.localPosition;
                pos.y = pos.y + d;
                mItemList[0].CachedRectTransform.localPosition = pos;
                UpdateAllShownItemsPos();
                return;
            }
        }
        else if (mArrangeType == ListItemArrangeType.LeftToRight)
        {
            if (contentSize <= viewPortSize)
            {
                Vector3 pos = mContainerTrans.localPosition;
                pos.x = 0;
                mContainerTrans.localPosition = pos;
                mItemList[0].CachedRectTransform.localPosition = new Vector3(0,mItemList[0].StartPosOffset, 0);
                UpdateAllShownItemsPos();
                return;
            }
            LoopListViewItem2 tViewItem0 = mItemList[0];
            tViewItem0.CachedRectTransform.GetWorldCorners(mItemWorldCorners);
            Vector3 leftPos0 = mViewPortRectTransform.InverseTransformPoint(mItemWorldCorners[1]);
            if (leftPos0.x > mViewPortRectLocalCorners[1].x)
            {
                Vector3 pos = mContainerTrans.localPosition;
                pos.x = 0;
                mContainerTrans.localPosition = pos;
                mItemList[0].CachedRectTransform.localPosition = new Vector3(0, mItemList[0].StartPosOffset, 0);
                UpdateAllShownItemsPos();
                return;
            }
            LoopListViewItem2 tViewItem1 = mItemList[mItemList.Count - 1];
            tViewItem1.CachedRectTransform.GetWorldCorners(mItemWorldCorners);
            Vector3 rightPos1 = mViewPortRectTransform.InverseTransformPoint(mItemWorldCorners[2]);
            float d = mViewPortRectLocalCorners[2].x - rightPos1.x;
            if (d > 0)
            {
                Vector3 pos = mItemList[0].CachedRectTransform.localPosition;
                pos.x = pos.x + d;
                mItemList[0].CachedRectTransform.localPosition = pos;
                UpdateAllShownItemsPos();
                return;
            }
        }
        else if (mArrangeType == ListItemArrangeType.RightToLeft)
        {
            if (contentSize <= viewPortSize)
            {
                Vector3 pos = mContainerTrans.localPosition;
                pos.x = 0;
                mContainerTrans.localPosition = pos;
                mItemList[0].CachedRectTransform.localPosition = new Vector3(0, mItemList[0].StartPosOffset, 0);
                UpdateAllShownItemsPos();
                return;
            }
            LoopListViewItem2 tViewItem0 = mItemList[0];
            tViewItem0.CachedRectTransform.GetWorldCorners(mItemWorldCorners);
            Vector3 rightPos0 = mViewPortRectTransform.InverseTransformPoint(mItemWorldCorners[2]);
            if (rightPos0.x < mViewPortRectLocalCorners[2].x)
            {
                Vector3 pos = mContainerTrans.localPosition;
                pos.x = 0;
                mContainerTrans.localPosition = pos;
                mItemList[0].CachedRectTransform.localPosition = new Vector3(0, mItemList[0].StartPosOffset, 0);
                UpdateAllShownItemsPos();
                return;
            }
            LoopListViewItem2 tViewItem1 = mItemList[mItemList.Count - 1];
            tViewItem1.CachedRectTransform.GetWorldCorners(mItemWorldCorners);
            Vector3 leftPos1 = mViewPortRectTransform.InverseTransformPoint(mItemWorldCorners[1]);
            float d = leftPos1.x - mViewPortRectLocalCorners[1].x;
            if (d > 0)
            {
                Vector3 pos = mItemList[0].CachedRectTransform.localPosition;
                pos.x = pos.x - d;
                mItemList[0].CachedRectTransform.localPosition = pos;
                UpdateAllShownItemsPos();
                return;
            }
        }



    }


    void Update()
    {
        if(mListViewInited == false)
        {
            return;
        }
        if(mNeedAdjustVec)
        {
            mNeedAdjustVec = false;
            if(mIsVertList)
            {
                if(mScrollRect.velocity.y * mAdjustedVec.y > 0)
                {
                    mScrollRect.velocity = mAdjustedVec;
                }
            }
            else
            {
                if (mScrollRect.velocity.x * mAdjustedVec.x > 0)
                {
                    mScrollRect.velocity = mAdjustedVec;
                }
            }
            
        }
        if (mSupportScrollBar)
        {
            mItemPosMgr.Update(false);
        }
        UpdateSnapMove();
        UpdateListView(mDistanceForRecycle0, mDistanceForRecycle1, mDistanceForNew0, mDistanceForNew1);
        ClearAllTmpRecycledItem();
        mLastFrameContainerPos = mContainerTrans.localPosition;
    }

    //update snap move. if immediate is set true, then the snap move will finish at once.
    void UpdateSnapMove(bool immediate = false)
    {
        if (mItemSnapEnable == false)
        {
            return;
        }
        if (mIsVertList)
        {
            UpdateSnapVertical(immediate);
        }
        else
        {
            UpdateSnapHorizontal(immediate);
        }
    }



    public void UpdateAllShownItemSnapData()
    {
        if (mItemSnapEnable == false)
        {
            return;
        }
        int count = mItemList.Count;
        if (count == 0)
        {
            return;
        }
        Vector3 pos = mContainerTrans.localPosition;
        LoopListViewItem2 tViewItem0 = mItemList[0];
        tViewItem0.CachedRectTransform.GetWorldCorners(mItemWorldCorners);
        float start = 0;
        float end = 0;
        float itemSnapCenter = 0;
        float snapCenter = 0;
        if (mArrangeType == ListItemArrangeType.TopToBottom)
        {
            snapCenter = -(1 - mViewPortSnapPivot.y) * mViewPortRectTransform.rect.height;
            Vector3 topPos1 = mViewPortRectTransform.InverseTransformPoint(mItemWorldCorners[1]);
            start = topPos1.y;
            end = start - tViewItem0.ItemSizeWithPadding;
            itemSnapCenter = start - tViewItem0.ItemSize * (1 - mItemSnapPivot.y);
            for (int i = 0; i < count; ++i)
            {
                mItemList[i].DistanceWithViewPortSnapCenter = snapCenter - itemSnapCenter;
                if ((i + 1) < count)
                {
                    start = end;
                    end = end - mItemList[i + 1].ItemSizeWithPadding;
                    itemSnapCenter = start - mItemList[i + 1].ItemSize * (1 - mItemSnapPivot.y);
                }
            }
        }
        else if (mArrangeType == ListItemArrangeType.BottomToTop)
        {
            snapCenter = mViewPortSnapPivot.y * mViewPortRectTransform.rect.height;
            Vector3 bottomPos1 = mViewPortRectTransform.InverseTransformPoint(mItemWorldCorners[0]);
            start = bottomPos1.y;
            end = start + tViewItem0.ItemSizeWithPadding;
            itemSnapCenter = start + tViewItem0.ItemSize * mItemSnapPivot.y;
            for (int i = 0; i < count; ++i)
            {
                mItemList[i].DistanceWithViewPortSnapCenter = snapCenter - itemSnapCenter;
                if ((i + 1) < count)
                {
                    start = end;
                    end = end + mItemList[i + 1].ItemSizeWithPadding;
                    itemSnapCenter = start + mItemList[i + 1].ItemSize * mItemSnapPivot.y;
                }
            }
        }
        else if (mArrangeType == ListItemArrangeType.RightToLeft)
        {
            snapCenter = -(1 - mViewPortSnapPivot.x) * mViewPortRectTransform.rect.width;
            Vector3 rightPos1 = mViewPortRectTransform.InverseTransformPoint(mItemWorldCorners[2]);
            start = rightPos1.x;
            end = start - tViewItem0.ItemSizeWithPadding;
            itemSnapCenter = start - tViewItem0.ItemSize * (1 - mItemSnapPivot.x);
            for (int i = 0; i < count; ++i)
            {
                mItemList[i].DistanceWithViewPortSnapCenter = snapCenter - itemSnapCenter;
                if ((i + 1) < count)
                {
                    start = end;
                    end = end - mItemList[i + 1].ItemSizeWithPadding;
                    itemSnapCenter = start - mItemList[i + 1].ItemSize * (1 - mItemSnapPivot.x);
                }
            }
        }
        else if (mArrangeType == ListItemArrangeType.LeftToRight)
        {
            snapCenter = mViewPortSnapPivot.x * mViewPortRectTransform.rect.width;
            Vector3 leftPos1 = mViewPortRectTransform.InverseTransformPoint(mItemWorldCorners[1]);
            start = leftPos1.x;
            end = start + tViewItem0.ItemSizeWithPadding;
            itemSnapCenter = start + tViewItem0.ItemSize * mItemSnapPivot.x;
            for (int i = 0; i < count; ++i)
            {
                mItemList[i].DistanceWithViewPortSnapCenter = snapCenter - itemSnapCenter;
                if ((i + 1) < count)
                {
                    start = end;
                    end = end + mItemList[i + 1].ItemSizeWithPadding;
                    itemSnapCenter = start + mItemList[i + 1].ItemSize * mItemSnapPivot.x;
                }
            }
        }
    }



    void UpdateSnapVertical(bool immediate = false)
    {
        if(mItemSnapEnable == false)
        {
            return;
        }
        int count = mItemList.Count;
        if (count == 0)
        {
            return;
        }
        Vector3 pos = mContainerTrans.localPosition;
        bool needCheck = (pos.y != mLastSnapCheckPos.y);
        mLastSnapCheckPos = pos;
        if (!needCheck)
        {
            if (mLeftSnapUpdateExtraCount > 0)
            {
                mLeftSnapUpdateExtraCount--;
                needCheck = true;
            }
        }
        if (needCheck)
        {
            LoopListViewItem2 tViewItem0 = mItemList[0];
            tViewItem0.CachedRectTransform.GetWorldCorners(mItemWorldCorners);
            int curIndex = -1;
            float start = 0;
            float end = 0;
            float itemSnapCenter = 0;
            float curMinDist = float.MaxValue;
            float curDist = 0;
            float curDistAbs = 0;
            float snapCenter = 0; 
            if (mArrangeType == ListItemArrangeType.TopToBottom)
            {
                snapCenter = -(1 - mViewPortSnapPivot.y) * mViewPortRectTransform.rect.height;
                Vector3 topPos1 = mViewPortRectTransform.InverseTransformPoint(mItemWorldCorners[1]);
                start = topPos1.y;
                end = start - tViewItem0.ItemSizeWithPadding;
                itemSnapCenter = start - tViewItem0.ItemSize * (1-mItemSnapPivot.y);
                for (int i = 0; i < count; ++i)
                {
                    curDist = snapCenter - itemSnapCenter;
                    curDistAbs = Mathf.Abs(curDist);
                    if (curDistAbs < curMinDist)
                    {
                        curMinDist = curDistAbs;
                        curIndex = i;
                    }
                    else
                    {
                        break;
                    }
                    
                    if ((i + 1) < count)
                    {
                        start = end;
                        end = end - mItemList[i + 1].ItemSizeWithPadding;
                        itemSnapCenter = start - mItemList[i + 1].ItemSize * (1 - mItemSnapPivot.y);
                    }
                }
            }
            else if(mArrangeType == ListItemArrangeType.BottomToTop)
            {
                snapCenter = mViewPortSnapPivot.y * mViewPortRectTransform.rect.height;
                Vector3 bottomPos1 = mViewPortRectTransform.InverseTransformPoint(mItemWorldCorners[0]);
                start = bottomPos1.y;
                end = start + tViewItem0.ItemSizeWithPadding;
                itemSnapCenter = start + tViewItem0.ItemSize * mItemSnapPivot.y;
                for (int i = 0; i < count; ++i)
                {
                    curDist = snapCenter - itemSnapCenter;
                    curDistAbs = Mathf.Abs(curDist);
                    if (curDistAbs < curMinDist)
                    {
                        curMinDist = curDistAbs;
                        curIndex = i;
                    }
                    else
                    {
                        break;
                    }

                    if ((i + 1) < count)
                    {
                        start = end;
                        end = end + mItemList[i + 1].ItemSizeWithPadding;
                        itemSnapCenter = start + mItemList[i + 1].ItemSize *  mItemSnapPivot.y;
                    }
                }
            }

            if (curIndex >= 0)
            {
                int oldNearestItemIndex = mCurSnapNearestItemIndex;
                mCurSnapNearestItemIndex = mItemList[curIndex].ItemIndex;
                if (mItemList[curIndex].ItemIndex != oldNearestItemIndex)
                {
                    if (mOnSnapNearestChanged != null)
                    {
                        mOnSnapNearestChanged(this,mItemList[curIndex]);
                    }
                }
            }
            else
            {
                mCurSnapNearestItemIndex = -1;
            }
        }
        bool canSnap = true;
        if(mScrollBarClickEventListener != null)
        {
            canSnap = !(mScrollBarClickEventListener.IsPressd);
        }
        float v = Mathf.Abs(mScrollRect.velocity.y);
        if (canSnap && !mIsDraging && v < mSnapVecThreshold)
        {
            UpdateCurSnapData();
            if (mCurSnapData.mSnapStatus != SnapStatus.SnapMoving)
            {
                return;
            }
            if (v > 0)
            {
                mScrollRect.StopMovement();
            }
            float old = mCurSnapData.mCurSnapVal;
            mCurSnapData.mCurSnapVal = Mathf.SmoothDamp(mCurSnapData.mCurSnapVal, mCurSnapData.mTargetSnapVal, ref mSmoothDumpVel, mSmoothDumpRate);
            float dt = mCurSnapData.mCurSnapVal - old;
            
            if (immediate || Mathf.Abs(mCurSnapData.mTargetSnapVal - mCurSnapData.mCurSnapVal) < mSnapFinishThreshold)
            {
                pos.y = pos.y + mCurSnapData.mTargetSnapVal - mCurSnapData.mCurSnapVal;
                mCurSnapData.mSnapStatus = SnapStatus.SnapMoveFinish;
                if (mOnSnapItemFinished != null)
                {
                    LoopListViewItem2 targetItem = GetShownItemByItemIndex(mCurSnapNearestItemIndex);
                    if(targetItem != null)
                    {
                        mOnSnapItemFinished(this,targetItem);
                    }
                }
            }
            else
            {
                pos.y = pos.y + dt;
            }

            if (mArrangeType == ListItemArrangeType.TopToBottom)
            {
                float maxY = mViewPortRectLocalCorners[0].y + mContainerTrans.rect.height;
                if (pos.y <= maxY && pos.y >= 0)
                {
                    mContainerTrans.localPosition = pos;
                }
            }
            else if (mArrangeType == ListItemArrangeType.BottomToTop)
            {
                float minY = mViewPortRectLocalCorners[1].y - mContainerTrans.rect.height;
                if (pos.y >= minY && pos.y <= 0)
                {
                    mContainerTrans.localPosition = pos;
                }
            }

        }

    }


    void UpdateCurSnapData()
    {
        int count = mItemList.Count;
        if (count == 0)
        {
            mCurSnapData.Clear();
            return;
        }

        if (mCurSnapData.mSnapStatus == SnapStatus.SnapMoving 
            || mCurSnapData.mSnapStatus == SnapStatus.SnapMoveFinish)
        {
            return;
        }
        if (mCurSnapData.mSnapStatus == SnapStatus.NoTargetSet)
        {
            LoopListViewItem2 nearestItem = GetShownItemByItemIndex(mCurSnapNearestItemIndex);
            if (nearestItem == null)
            {
                return;
            }
            mCurSnapData.mSnapTargetIndex = mCurSnapNearestItemIndex;
            mCurSnapData.mSnapStatus = SnapStatus.TargetHasSet;
        }
        if (mCurSnapData.mSnapStatus == SnapStatus.TargetHasSet)
        {
            LoopListViewItem2 targetItem = GetShownItemByItemIndex(mCurSnapData.mSnapTargetIndex);
            if (targetItem == null)
            {
                mCurSnapData.Clear();
                return;
            }
            UpdateAllShownItemSnapData();
            mCurSnapData.mTargetSnapVal = targetItem.DistanceWithViewPortSnapCenter;
            mCurSnapData.mCurSnapVal = 0;
            mCurSnapData.mSnapStatus = SnapStatus.SnapMoving;
        }

    }
    //Clear current snap target and then the LoopScrollView2 will auto snap to the CurSnapNearestItemIndex.
    //清除当前的snap目标,然后LoopScrollView2将自动吸附到cursnapnear estitemindex。
    public void ClearSnapData()
    {
        mCurSnapData.Clear();
    }

    public void SetSnapTargetItemIndex(int itemIndex)
    {
        mCurSnapData.mSnapTargetIndex = itemIndex;
        mCurSnapData.mSnapStatus = SnapStatus.TargetHasSet;
    }

    //Get the nearest item index with the viewport snap point.
    //使用viewport快照点获取最近的项目索引。
    public int CurSnapNearestItemIndex
    {
        get{ return mCurSnapNearestItemIndex; }
    }

    public void ForceSnapUpdateCheck()
    {
        if(mLeftSnapUpdateExtraCount <= 0)
        {
            mLeftSnapUpdateExtraCount = 1;
        }
    }

    void UpdateSnapHorizontal(bool immediate = false)
    {
        if (mItemSnapEnable == false)
        {
            return;
        }
        int count = mItemList.Count;
        if (count == 0)
        {
            return;
        }
        Vector3 pos = mContainerTrans.localPosition;
        bool needCheck = (pos.x != mLastSnapCheckPos.x);
        mLastSnapCheckPos = pos;
        if (!needCheck)
        {
            if(mLeftSnapUpdateExtraCount > 0)
            {
                mLeftSnapUpdateExtraCount--;
                needCheck = true;
            }
        }
        if (needCheck)
        {
            LoopListViewItem2 tViewItem0 = mItemList[0];
            tViewItem0.CachedRectTransform.GetWorldCorners(mItemWorldCorners);
            int curIndex = -1;
            float start = 0;
            float end = 0;
            float itemSnapCenter = 0;
            float curMinDist = float.MaxValue;
            float curDist = 0;
            float curDistAbs = 0;
            float snapCenter = 0;
            if (mArrangeType == ListItemArrangeType.RightToLeft)
            {
                snapCenter = -(1 - mViewPortSnapPivot.x) * mViewPortRectTransform.rect.width;
                Vector3 rightPos1 = mViewPortRectTransform.InverseTransformPoint(mItemWorldCorners[2]);
                start = rightPos1.x;
                end = start - tViewItem0.ItemSizeWithPadding;
                itemSnapCenter = start - tViewItem0.ItemSize * (1 - mItemSnapPivot.x);
                for (int i = 0; i < count; ++i)
                {
                    curDist = snapCenter - itemSnapCenter;
                    curDistAbs = Mathf.Abs(curDist);
                    if (curDistAbs < curMinDist)
                    {
                        curMinDist = curDistAbs;
                        curIndex = i;
                    }
                    else
                    {
                        break;
                    }

                    if ((i + 1) < count)
                    {
                        start = end;
                        end = end - mItemList[i + 1].ItemSizeWithPadding;
                        itemSnapCenter = start - mItemList[i + 1].ItemSize * (1 - mItemSnapPivot.x);
                    }
                }
            }
            else if (mArrangeType == ListItemArrangeType.LeftToRight)
            {
                snapCenter = mViewPortSnapPivot.x * mViewPortRectTransform.rect.width;
                Vector3 leftPos1 = mViewPortRectTransform.InverseTransformPoint(mItemWorldCorners[1]);
                start = leftPos1.x;
                end = start + tViewItem0.ItemSizeWithPadding;
                itemSnapCenter = start + tViewItem0.ItemSize * mItemSnapPivot.x;
                for (int i = 0; i < count; ++i)
                {
                    curDist = snapCenter - itemSnapCenter;
                    curDistAbs = Mathf.Abs(curDist);
                    if (curDistAbs < curMinDist)
                    {
                        curMinDist = curDistAbs;
                        curIndex = i;
                    }
                    else
                    {
                        break;
                    }

                    if ((i + 1) < count)
                    {
                        start = end;
                        end = end + mItemList[i + 1].ItemSizeWithPadding;
                        itemSnapCenter = start + mItemList[i + 1].ItemSize * mItemSnapPivot.x;
                    }
                }
            }


            if (curIndex >= 0)
            {
                int oldNearestItemIndex = mCurSnapNearestItemIndex;
                mCurSnapNearestItemIndex = mItemList[curIndex].ItemIndex;
                if (mItemList[curIndex].ItemIndex != oldNearestItemIndex)
                {
                    if (mOnSnapNearestChanged != null)
                    {
                        mOnSnapNearestChanged(this, mItemList[curIndex]);
                    }
                }
            }
            else
            {
                mCurSnapNearestItemIndex = -1;
            }
        }
        bool canSnap = true;
        if (mScrollBarClickEventListener != null)
        {
            canSnap = !(mScrollBarClickEventListener.IsPressd);
        }
        float v = Mathf.Abs(mScrollRect.velocity.x);
        if (canSnap && !mIsDraging && v < mSnapVecThreshold)
        {
            UpdateCurSnapData();
            if(mCurSnapData.mSnapStatus != SnapStatus.SnapMoving)
            {
                return;
            }
            if (v > 0)
            {
                mScrollRect.StopMovement();
            }
            float old = mCurSnapData.mCurSnapVal;
            mCurSnapData.mCurSnapVal = Mathf.SmoothDamp(mCurSnapData.mCurSnapVal, mCurSnapData.mTargetSnapVal, ref mSmoothDumpVel, mSmoothDumpRate);
            float dt = mCurSnapData.mCurSnapVal - old;

            if (immediate || Mathf.Abs(mCurSnapData.mTargetSnapVal - mCurSnapData.mCurSnapVal) < mSnapFinishThreshold)
            {
                pos.x = pos.x + mCurSnapData.mTargetSnapVal - mCurSnapData.mCurSnapVal;
                mCurSnapData.mSnapStatus = SnapStatus.SnapMoveFinish;
                if (mOnSnapItemFinished != null)
                {
                    LoopListViewItem2 targetItem = GetShownItemByItemIndex(mCurSnapNearestItemIndex);
                    if (targetItem != null)
                    {
                        mOnSnapItemFinished(this, targetItem);
                    }
                }
            }
            else
            {
                pos.x = pos.x + dt;
            }
            
            if (mArrangeType == ListItemArrangeType.LeftToRight)
            {
                float minX = mViewPortRectLocalCorners[2].x - mContainerTrans.rect.width;
                if(pos.x >= minX && pos.x <= 0)
                {
                    mContainerTrans.localPosition = pos;
                }
            }
            else if (mArrangeType == ListItemArrangeType.RightToLeft)
            {
                float maxX = mViewPortRectLocalCorners[1].x + mContainerTrans.rect.width;
                if (pos.x <= maxX && pos.x >= 0)
                {
                    mContainerTrans.localPosition = pos;
                }
            }

        }

    }


    public void UpdateListView(float distanceForRecycle0, float distanceForRecycle1, float distanceForNew0, float distanceForNew1)
    {
        mListUpdateCheckFrameCount++;
        if (mIsVertList)
        {
            bool needContinueCheck = true;
            int checkCount = 0;
            int maxCount = 9999;
            while (needContinueCheck)
            {
                checkCount++;
                if(checkCount >= maxCount)
                {
                    Debug.LogError("UpdateListView Vertical while loop " + checkCount + " times! something is wrong!");
                    break;
                }
                needContinueCheck = UpdateForVertList(distanceForRecycle0, distanceForRecycle1, distanceForNew0, distanceForNew1);
            }
        }
        else
        {
            bool needContinueCheck = true;
            int checkCount = 0;
            int maxCount = 9999;
            while (needContinueCheck)
            {
                checkCount++;
                if (checkCount >= maxCount)
                {
                    Debug.LogError("UpdateListView  Horizontal while loop " + checkCount + " times! something is wrong!");
                    break;
                }
                needContinueCheck = UpdateForHorizontalList(distanceForRecycle0, distanceForRecycle1, distanceForNew0, distanceForNew1);
            }
        }

    }



    bool UpdateForVertList(float distanceForRecycle0,float distanceForRecycle1,float distanceForNew0, float distanceForNew1)
    {
        if (mItemTotalCount == 0)
        {
            if(mItemList.Count > 0)
            {
                RecycleAllItem();
            }
            return false;
        }
        if (mArrangeType == ListItemArrangeType.TopToBottom)
        {
            int itemListCount = mItemList.Count;
            if (itemListCount == 0)
            {
                float curY = mContainerTrans.localPosition.y;
                if (curY < 0)
                {
                    curY = 0;
                }
                int index = 0;
                float pos = -curY;
                if (mSupportScrollBar)
                {
                    GetPlusItemIndexAndPosAtGivenPos(curY, ref index, ref pos);
                    pos = -pos;
                }
                LoopListViewItem2 newItem = GetNewItemByIndex(index);
                if (newItem == null)
                {
                    return false;
                }
                if (mSupportScrollBar)
                {
                    SetItemSize(index, newItem.CachedRectTransform.rect.height, newItem.Padding);
                }
                mItemList.Add(newItem);
                newItem.CachedRectTransform.localPosition = new Vector3(newItem.StartPosOffset, pos, 0);
                UpdateContentSize();
                return true;
            }
            LoopListViewItem2 tViewItem0 = mItemList[0];
            tViewItem0.CachedRectTransform.GetWorldCorners(mItemWorldCorners);
            Vector3 topPos0 = mViewPortRectTransform.InverseTransformPoint(mItemWorldCorners[1]);
            Vector3 downPos0 = mViewPortRectTransform.InverseTransformPoint(mItemWorldCorners[0]);

            if (!mIsDraging && tViewItem0.ItemCreatedCheckFrameCount != mListUpdateCheckFrameCount
                && downPos0.y - mViewPortRectLocalCorners[1].y > distanceForRecycle0)
            {
                mItemList.RemoveAt(0);
                RecycleItemTmp(tViewItem0);
                if (!mSupportScrollBar)
                {
                    UpdateContentSize();
                    CheckIfNeedUpdataItemPos();
                }
                return true;
            }

            LoopListViewItem2 tViewItem1 = mItemList[mItemList.Count - 1];
            tViewItem1.CachedRectTransform.GetWorldCorners(mItemWorldCorners);
            Vector3 topPos1 = mViewPortRectTransform.InverseTransformPoint(mItemWorldCorners[1]);
            Vector3 downPos1 = mViewPortRectTransform.InverseTransformPoint(mItemWorldCorners[0]);
            if (!mIsDraging && tViewItem1.ItemCreatedCheckFrameCount != mListUpdateCheckFrameCount
                && mViewPortRectLocalCorners[0].y - topPos1.y > distanceForRecycle1)
            {
                mItemList.RemoveAt(mItemList.Count - 1);
                RecycleItemTmp(tViewItem1);
                if (!mSupportScrollBar)
                {
                    UpdateContentSize();
                    CheckIfNeedUpdataItemPos();
                }
                return true;
            }



            if (mViewPortRectLocalCorners[0].y - downPos1.y < distanceForNew1)
            {
                if(tViewItem1.ItemIndex > mCurReadyMaxItemIndex)
                {
                    mCurReadyMaxItemIndex = tViewItem1.ItemIndex;
                    mNeedCheckNextMaxItem = true;
                }
                int nIndex = tViewItem1.ItemIndex + 1;
                if (nIndex <= mCurReadyMaxItemIndex || mNeedCheckNextMaxItem)
                {
                    LoopListViewItem2 newItem = GetNewItemByIndex(nIndex);
                    if (newItem == null)
                    {
                        mCurReadyMaxItemIndex = tViewItem1.ItemIndex;
                        mNeedCheckNextMaxItem = false;
                        CheckIfNeedUpdataItemPos();
                    }
                    else
                    {
                        if (mSupportScrollBar)
                        {
                            SetItemSize(nIndex, newItem.CachedRectTransform.rect.height, newItem.Padding);
                        }
                        mItemList.Add(newItem);
                        float y = tViewItem1.CachedRectTransform.localPosition.y - tViewItem1.CachedRectTransform.rect.height - tViewItem1.Padding;
                        newItem.CachedRectTransform.localPosition = new Vector3(newItem.StartPosOffset, y, 0);
                        UpdateContentSize();
                        CheckIfNeedUpdataItemPos();

                        if (nIndex > mCurReadyMaxItemIndex)
                        {
                            mCurReadyMaxItemIndex = nIndex;
                        }
                        return true;
                    }
                    
                }

            }

            if (topPos0.y - mViewPortRectLocalCorners[1].y < distanceForNew0)
            {
                if(tViewItem0.ItemIndex < mCurReadyMinItemIndex)
                {
                    mCurReadyMinItemIndex = tViewItem0.ItemIndex;
                    mNeedCheckNextMinItem = true;
                }
                int nIndex = tViewItem0.ItemIndex - 1;
                if (nIndex >= mCurReadyMinItemIndex || mNeedCheckNextMinItem)
                {
                    LoopListViewItem2 newItem = GetNewItemByIndex(nIndex);
                    if (newItem == null)
                    {
                        mCurReadyMinItemIndex = tViewItem0.ItemIndex;
                        mNeedCheckNextMinItem = false;
                    }
                    else
                    {
                        if (mSupportScrollBar)
                        {
                            SetItemSize(nIndex, newItem.CachedRectTransform.rect.height, newItem.Padding);
                        }
                        mItemList.Insert(0, newItem);
                        float y = tViewItem0.CachedRectTransform.localPosition.y + newItem.CachedRectTransform.rect.height + newItem.Padding;
                        newItem.CachedRectTransform.localPosition = new Vector3(newItem.StartPosOffset, y, 0);
                        UpdateContentSize();
                        CheckIfNeedUpdataItemPos();
                        if (nIndex < mCurReadyMinItemIndex)
                        {
                            mCurReadyMinItemIndex = nIndex;
                        }
                        return true;
                    }
                    
                }

            }

        }
        else
        {
            
            if (mItemList.Count == 0)
            {
                float curY = mContainerTrans.localPosition.y;
                if (curY > 0)
                {
                    curY = 0;
                }
                int index = 0;
                float pos = -curY;
                if (mSupportScrollBar)
                {
                    GetPlusItemIndexAndPosAtGivenPos(-curY, ref index, ref pos);
                }
                LoopListViewItem2 newItem = GetNewItemByIndex(index);
                if (newItem == null)
                {
                    return false;
                }
                if (mSupportScrollBar)
                {
                    SetItemSize(index, newItem.CachedRectTransform.rect.height, newItem.Padding);
                }
                mItemList.Add(newItem);
                newItem.CachedRectTransform.localPosition = new Vector3(newItem.StartPosOffset, pos, 0);
                UpdateContentSize();
                return true;
            }
            LoopListViewItem2 tViewItem0 = mItemList[0];
            tViewItem0.CachedRectTransform.GetWorldCorners(mItemWorldCorners);
            Vector3 topPos0 = mViewPortRectTransform.InverseTransformPoint(mItemWorldCorners[1]);
            Vector3 downPos0 = mViewPortRectTransform.InverseTransformPoint(mItemWorldCorners[0]);

            if (!mIsDraging && tViewItem0.ItemCreatedCheckFrameCount != mListUpdateCheckFrameCount
                && mViewPortRectLocalCorners[0].y - topPos0.y > distanceForRecycle0)
            {
                mItemList.RemoveAt(0);
                RecycleItemTmp(tViewItem0);
                if (!mSupportScrollBar)
                {
                    UpdateContentSize();
                    CheckIfNeedUpdataItemPos();
                }
                return true;
            }

            LoopListViewItem2 tViewItem1 = mItemList[mItemList.Count - 1];
            tViewItem1.CachedRectTransform.GetWorldCorners(mItemWorldCorners);
            Vector3 topPos1 = mViewPortRectTransform.InverseTransformPoint(mItemWorldCorners[1]);
            Vector3 downPos1 = mViewPortRectTransform.InverseTransformPoint(mItemWorldCorners[0]);
            if (!mIsDraging && tViewItem1.ItemCreatedCheckFrameCount != mListUpdateCheckFrameCount
                 && downPos1.y - mViewPortRectLocalCorners[1].y > distanceForRecycle1)
            {
                mItemList.RemoveAt(mItemList.Count - 1);
                RecycleItemTmp(tViewItem1);
                if (!mSupportScrollBar)
                {
                    UpdateContentSize();
                    CheckIfNeedUpdataItemPos();
                }
                return true;
            }

            if (topPos1.y - mViewPortRectLocalCorners[1].y < distanceForNew1)
            {
                if (tViewItem1.ItemIndex > mCurReadyMaxItemIndex)
                {
                    mCurReadyMaxItemIndex = tViewItem1.ItemIndex;
                    mNeedCheckNextMaxItem = true;
                }
                int nIndex = tViewItem1.ItemIndex + 1;
                if (nIndex <= mCurReadyMaxItemIndex || mNeedCheckNextMaxItem)
                {
                    LoopListViewItem2 newItem = GetNewItemByIndex(nIndex);
                    if (newItem == null)
                    {
                        mNeedCheckNextMaxItem = false;
                        CheckIfNeedUpdataItemPos();
                    }
                    else
                    {
                        if (mSupportScrollBar)
                        {
                            SetItemSize(nIndex, newItem.CachedRectTransform.rect.height, newItem.Padding);
                        }
                        mItemList.Add(newItem);
                        float y = tViewItem1.CachedRectTransform.localPosition.y + tViewItem1.CachedRectTransform.rect.height + tViewItem1.Padding;
                        newItem.CachedRectTransform.localPosition = new Vector3(newItem.StartPosOffset, y, 0);
                        UpdateContentSize();
                        CheckIfNeedUpdataItemPos();
                        if (nIndex > mCurReadyMaxItemIndex)
                        {
                            mCurReadyMaxItemIndex = nIndex;
                        }
                        return true;
                    }
                    
                }

            }


            if (mViewPortRectLocalCorners[0].y - downPos0.y < distanceForNew0)
            {
                if (tViewItem0.ItemIndex < mCurReadyMinItemIndex)
                {
                    mCurReadyMinItemIndex = tViewItem0.ItemIndex;
                    mNeedCheckNextMinItem = true;
                }
                int nIndex = tViewItem0.ItemIndex - 1;
                if (nIndex >= mCurReadyMinItemIndex || mNeedCheckNextMinItem)
                {
                    LoopListViewItem2 newItem = GetNewItemByIndex(nIndex);
                    if (newItem == null)
                    {
                        mNeedCheckNextMinItem = false;
                        return false;
                    }
                    else
                    {
                        if (mSupportScrollBar)
                        {
                            SetItemSize(nIndex, newItem.CachedRectTransform.rect.height, newItem.Padding);
                        }
                        mItemList.Insert(0, newItem);
                        float y = tViewItem0.CachedRectTransform.localPosition.y - newItem.CachedRectTransform.rect.height - newItem.Padding;
                        newItem.CachedRectTransform.localPosition = new Vector3(newItem.StartPosOffset, y, 0);
                        UpdateContentSize();
                        CheckIfNeedUpdataItemPos();
                        if (nIndex < mCurReadyMinItemIndex)
                        {
                            mCurReadyMinItemIndex = nIndex;
                        }
                        return true;
                    }
                    
                }
            }


        }

        return false;

    }





    bool UpdateForHorizontalList(float distanceForRecycle0, float distanceForRecycle1, float distanceForNew0, float distanceForNew1)
    {
        if (mItemTotalCount == 0)
        {
            if (mItemList.Count > 0)
            {
                RecycleAllItem();
            }
            return false;
        }
        if (mArrangeType == ListItemArrangeType.LeftToRight)
        {

            if (mItemList.Count == 0)
            {
                float curX = mContainerTrans.localPosition.x;
                if (curX > 0)
                {
                    curX = 0;
                }
                int index = 0;
                float pos = -curX;
                if (mSupportScrollBar)
                {
                    GetPlusItemIndexAndPosAtGivenPos(-curX, ref index, ref pos);
                }
                LoopListViewItem2 newItem = GetNewItemByIndex(index);
                if (newItem == null)
                {
                    return false;
                }
                if (mSupportScrollBar)
                {
                    SetItemSize(index, newItem.CachedRectTransform.rect.width, newItem.Padding);
                }
                mItemList.Add(newItem);
                newItem.CachedRectTransform.localPosition = new Vector3(pos, newItem.StartPosOffset, 0);
                UpdateContentSize();
                return true;
            }
            LoopListViewItem2 tViewItem0 = mItemList[0];
            tViewItem0.CachedRectTransform.GetWorldCorners(mItemWorldCorners);
            Vector3 leftPos0 = mViewPortRectTransform.InverseTransformPoint(mItemWorldCorners[1]);
            Vector3 rightPos0 = mViewPortRectTransform.InverseTransformPoint(mItemWorldCorners[2]);

            if (!mIsDraging && tViewItem0.ItemCreatedCheckFrameCount != mListUpdateCheckFrameCount
                && mViewPortRectLocalCorners[1].x - rightPos0.x > distanceForRecycle0)
            {
                mItemList.RemoveAt(0);
                RecycleItemTmp(tViewItem0);
                if (!mSupportScrollBar)
                {
                    UpdateContentSize();
                    CheckIfNeedUpdataItemPos();
                }
                return true;
            }

            LoopListViewItem2 tViewItem1 = mItemList[mItemList.Count - 1];
            tViewItem1.CachedRectTransform.GetWorldCorners(mItemWorldCorners);
            Vector3 leftPos1 = mViewPortRectTransform.InverseTransformPoint(mItemWorldCorners[1]);
            Vector3 rightPos1 = mViewPortRectTransform.InverseTransformPoint(mItemWorldCorners[2]);
            if (!mIsDraging && tViewItem1.ItemCreatedCheckFrameCount != mListUpdateCheckFrameCount
                && leftPos1.x - mViewPortRectLocalCorners[2].x> distanceForRecycle1)
            {
                mItemList.RemoveAt(mItemList.Count - 1);
                RecycleItemTmp(tViewItem1);
                if (!mSupportScrollBar)
                {
                    UpdateContentSize();
                    CheckIfNeedUpdataItemPos();
                }
                return true;
            }



            if (rightPos1.x - mViewPortRectLocalCorners[2].x < distanceForNew1)
            {
                if (tViewItem1.ItemIndex > mCurReadyMaxItemIndex)
                {
                    mCurReadyMaxItemIndex = tViewItem1.ItemIndex;
                    mNeedCheckNextMaxItem = true;
                }
                int nIndex = tViewItem1.ItemIndex + 1;
                if (nIndex <= mCurReadyMaxItemIndex || mNeedCheckNextMaxItem)
                {
                    LoopListViewItem2 newItem = GetNewItemByIndex(nIndex);
                    if (newItem == null)
                    {
                        mCurReadyMaxItemIndex = tViewItem1.ItemIndex;
                        mNeedCheckNextMaxItem = false;
                        CheckIfNeedUpdataItemPos();
                    }
                    else
                    {
                        if (mSupportScrollBar)
                        {
                            SetItemSize(nIndex, newItem.CachedRectTransform.rect.width, newItem.Padding);
                        }
                        mItemList.Add(newItem);
                        float x = tViewItem1.CachedRectTransform.localPosition.x + tViewItem1.CachedRectTransform.rect.width + tViewItem1.Padding;
                        newItem.CachedRectTransform.localPosition = new Vector3(x, newItem.StartPosOffset, 0);
                        UpdateContentSize();
                        CheckIfNeedUpdataItemPos();

                        if (nIndex > mCurReadyMaxItemIndex)
                        {
                            mCurReadyMaxItemIndex = nIndex;
                        }
                        return true;
                    }

                }

            }

            if ( mViewPortRectLocalCorners[1].x - leftPos0.x < distanceForNew0)
            {
                if (tViewItem0.ItemIndex < mCurReadyMinItemIndex)
                {
                    mCurReadyMinItemIndex = tViewItem0.ItemIndex;
                    mNeedCheckNextMinItem = true;
                }
                int nIndex = tViewItem0.ItemIndex - 1;
                if (nIndex >= mCurReadyMinItemIndex || mNeedCheckNextMinItem)
                {
                    LoopListViewItem2 newItem = GetNewItemByIndex(nIndex);
                    if (newItem == null)
                    {
                        mCurReadyMinItemIndex = tViewItem0.ItemIndex;
                        mNeedCheckNextMinItem = false;
                    }
                    else
                    {
                        if (mSupportScrollBar)
                        {
                            SetItemSize(nIndex, newItem.CachedRectTransform.rect.width, newItem.Padding);
                        }
                        mItemList.Insert(0, newItem);
                        float x = tViewItem0.CachedRectTransform.localPosition.x - newItem.CachedRectTransform.rect.width - newItem.Padding;
                        newItem.CachedRectTransform.localPosition = new Vector3(x, newItem.StartPosOffset, 0);
                        UpdateContentSize();
                        CheckIfNeedUpdataItemPos();
                        if (nIndex < mCurReadyMinItemIndex)
                        {
                            mCurReadyMinItemIndex = nIndex;
                        }
                        return true;
                    }

                }

            }

        }
        else
        {

            if (mItemList.Count == 0)
            {
                float curX = mContainerTrans.localPosition.x;
                if (curX < 0)
                {
                    curX = 0;
                }
                int index = 0;
                float pos = -curX;
                if (mSupportScrollBar)
                {
                    GetPlusItemIndexAndPosAtGivenPos(curX, ref index, ref pos);
                    pos = -pos;
                }
                LoopListViewItem2 newItem = GetNewItemByIndex(index);
                if (newItem == null)
                {
                    return false;
                }
                if (mSupportScrollBar)
                {
                    SetItemSize(index, newItem.CachedRectTransform.rect.width, newItem.Padding);
                }
                mItemList.Add(newItem);
                newItem.CachedRectTransform.localPosition = new Vector3(pos, newItem.StartPosOffset, 0);
                UpdateContentSize();
                return true;
            }
            LoopListViewItem2 tViewItem0 = mItemList[0];
            tViewItem0.CachedRectTransform.GetWorldCorners(mItemWorldCorners);
            Vector3 leftPos0 = mViewPortRectTransform.InverseTransformPoint(mItemWorldCorners[1]);
            Vector3 rightPos0 = mViewPortRectTransform.InverseTransformPoint(mItemWorldCorners[2]);

            if (!mIsDraging && tViewItem0.ItemCreatedCheckFrameCount != mListUpdateCheckFrameCount
                && leftPos0.x - mViewPortRectLocalCorners[2].x > distanceForRecycle0)
            {
                mItemList.RemoveAt(0);
                RecycleItemTmp(tViewItem0);
                if (!mSupportScrollBar)
                {
                    UpdateContentSize();
                    CheckIfNeedUpdataItemPos();
                }
                return true;
            }

            LoopListViewItem2 tViewItem1 = mItemList[mItemList.Count - 1];
            tViewItem1.CachedRectTransform.GetWorldCorners(mItemWorldCorners);
            Vector3 leftPos1 = mViewPortRectTransform.InverseTransformPoint(mItemWorldCorners[1]);
            Vector3 rightPos1 = mViewPortRectTransform.InverseTransformPoint(mItemWorldCorners[2]);
            if (!mIsDraging && tViewItem1.ItemCreatedCheckFrameCount != mListUpdateCheckFrameCount
                && mViewPortRectLocalCorners[1].x - rightPos1.x > distanceForRecycle1)
            {
                mItemList.RemoveAt(mItemList.Count - 1);
                RecycleItemTmp(tViewItem1);
                if (!mSupportScrollBar)
                {
                    UpdateContentSize();
                    CheckIfNeedUpdataItemPos();
                }
                return true;
            }



            if (mViewPortRectLocalCorners[1].x - leftPos1.x  < distanceForNew1)
            {
                if (tViewItem1.ItemIndex > mCurReadyMaxItemIndex)
                {
                    mCurReadyMaxItemIndex = tViewItem1.ItemIndex;
                    mNeedCheckNextMaxItem = true;
                }
                int nIndex = tViewItem1.ItemIndex + 1;
                if (nIndex <= mCurReadyMaxItemIndex || mNeedCheckNextMaxItem)
                {
                    LoopListViewItem2 newItem = GetNewItemByIndex(nIndex);
                    if (newItem == null)
                    {
                        mCurReadyMaxItemIndex = tViewItem1.ItemIndex;
                        mNeedCheckNextMaxItem = false;
                        CheckIfNeedUpdataItemPos();
                    }
                    else
                    {
                        if (mSupportScrollBar)
                        {
                            SetItemSize(nIndex, newItem.CachedRectTransform.rect.width, newItem.Padding);
                        }
                        mItemList.Add(newItem);
                        float x = tViewItem1.CachedRectTransform.localPosition.x - tViewItem1.CachedRectTransform.rect.width - tViewItem1.Padding;
                        newItem.CachedRectTransform.localPosition = new Vector3(x, newItem.StartPosOffset, 0);
                        UpdateContentSize();
                        CheckIfNeedUpdataItemPos();

                        if (nIndex > mCurReadyMaxItemIndex)
                        {
                            mCurReadyMaxItemIndex = nIndex;
                        }
                        return true;
                    }

                }

            }

            if (rightPos0.x - mViewPortRectLocalCorners[2].x < distanceForNew0)
            {
                if (tViewItem0.ItemIndex < mCurReadyMinItemIndex)
                {
                    mCurReadyMinItemIndex = tViewItem0.ItemIndex;
                    mNeedCheckNextMinItem = true;
                }
                int nIndex = tViewItem0.ItemIndex - 1;
                if (nIndex >= mCurReadyMinItemIndex || mNeedCheckNextMinItem)
                {
                    LoopListViewItem2 newItem = GetNewItemByIndex(nIndex);
                    if (newItem == null)
                    {
                        mCurReadyMinItemIndex = tViewItem0.ItemIndex;
                        mNeedCheckNextMinItem = false;
                    }
                    else
                    {
                        if (mSupportScrollBar)
                        {
                            SetItemSize(nIndex, newItem.CachedRectTransform.rect.width, newItem.Padding);
                        }
                        mItemList.Insert(0, newItem);
                        float x = tViewItem0.CachedRectTransform.localPosition.x + newItem.CachedRectTransform.rect.width + newItem.Padding;
                        newItem.CachedRectTransform.localPosition = new Vector3(x, newItem.StartPosOffset, 0);
                        UpdateContentSize();
                        CheckIfNeedUpdataItemPos();
                        if (nIndex < mCurReadyMinItemIndex)
                        {
                            mCurReadyMinItemIndex = nIndex;
                        }
                        return true;
                    }

                }

            }

        }

        return false;

    }






    float GetContentPanelSize()
    {
        if (mSupportScrollBar)
        {
            float tTotalSize = mItemPosMgr.mTotalSize > 0 ? (mItemPosMgr.mTotalSize - mLastItemPadding) : 0;
            if(tTotalSize < 0)
            {
                tTotalSize = 0;
            }
            return tTotalSize;
        }
        int count = mItemList.Count;
        if (count == 0)
        {
            return 0;
        }
        if (count == 1)
        {
            return mItemList[0].ItemSize;
        }
        if (count == 2)
        {
            return mItemList[0].ItemSizeWithPadding + mItemList[1].ItemSize;
        }
        float s = 0;
        for (int i = 0; i < count - 1; ++i)
        {
            s += mItemList[i].ItemSizeWithPadding;
        }
        s += mItemList[count - 1].ItemSize;
        return s;
    }


    void CheckIfNeedUpdataItemPos()
    {
        int count = mItemList.Count;
        if (count == 0)
        {
            return;
        }
        if (mArrangeType == ListItemArrangeType.TopToBottom)
        {
            LoopListViewItem2 firstItem = mItemList[0];
            LoopListViewItem2 lastItem = mItemList[mItemList.Count - 1];
            float viewMaxY = GetContentPanelSize();
            if (firstItem.TopY > 0 || (firstItem.ItemIndex == mCurReadyMinItemIndex && firstItem.TopY != 0))
            {
                UpdateAllShownItemsPos();
                return;
            }
            if ((-lastItem.BottomY) > viewMaxY || (lastItem.ItemIndex == mCurReadyMaxItemIndex && (-lastItem.BottomY) != viewMaxY))
            {
                UpdateAllShownItemsPos();
                return;
            }

        }
        else if (mArrangeType == ListItemArrangeType.BottomToTop)
        {
            LoopListViewItem2 firstItem = mItemList[0];
            LoopListViewItem2 lastItem = mItemList[mItemList.Count - 1];
            float viewMaxY = GetContentPanelSize();
            if (firstItem.BottomY < 0 || (firstItem.ItemIndex == mCurReadyMinItemIndex && firstItem.BottomY != 0))
            {
                UpdateAllShownItemsPos();
                return;
            }
            if (lastItem.TopY > viewMaxY || (lastItem.ItemIndex == mCurReadyMaxItemIndex && lastItem.TopY != viewMaxY))
            {
                UpdateAllShownItemsPos();
                return;
            }
        }
        else if (mArrangeType == ListItemArrangeType.LeftToRight)
        {
            LoopListViewItem2 firstItem = mItemList[0];
            LoopListViewItem2 lastItem = mItemList[mItemList.Count - 1];
            float viewMaxX = GetContentPanelSize();
            if (firstItem.LeftX < 0 || (firstItem.ItemIndex == mCurReadyMinItemIndex && firstItem.LeftX != 0))
            {
                UpdateAllShownItemsPos();
                return;
            }
            if ((lastItem.RightX) > viewMaxX || (lastItem.ItemIndex == mCurReadyMaxItemIndex && lastItem.RightX != viewMaxX))
            {
                UpdateAllShownItemsPos();
                return;
            }

        }
        else if (mArrangeType == ListItemArrangeType.RightToLeft)
        {
            LoopListViewItem2 firstItem = mItemList[0];
            LoopListViewItem2 lastItem = mItemList[mItemList.Count - 1];
            float viewMaxX = GetContentPanelSize();
            if (firstItem.RightX > 0 || (firstItem.ItemIndex == mCurReadyMinItemIndex && firstItem.RightX != 0))
            {
                UpdateAllShownItemsPos();
                return;
            }
            if ((-lastItem.LeftX) > viewMaxX || (lastItem.ItemIndex == mCurReadyMaxItemIndex && (-lastItem.LeftX) != viewMaxX))
            {
                UpdateAllShownItemsPos();
                return;
            }

        }

    }


    void UpdateAllShownItemsPos()
    {
        int count = mItemList.Count;
        if (count == 0)
        {
            return;
        }

        mAdjustedVec = (mContainerTrans.localPosition - mLastFrameContainerPos) / Time.deltaTime;

        if (mArrangeType == ListItemArrangeType.TopToBottom)
        {
            float pos = 0;
            if (mSupportScrollBar)
            {
                pos = -GetItemPos(mItemList[0].ItemIndex);
            }
            float pos1 = mItemList[0].CachedRectTransform.localPosition.y;
            float d = pos - pos1;
            float curY = pos;
            for (int i = 0; i < count; ++i)
            {
                LoopListViewItem2 item = mItemList[i];
                item.CachedRectTransform.localPosition = new Vector3(item.StartPosOffset, curY, 0);
                curY = curY - item.CachedRectTransform.rect.height - item.Padding;
            }
            if(d != 0)
            {
                Vector2 p = mContainerTrans.localPosition;
                p.y = p.y - d;
                mContainerTrans.localPosition = p;
            }
            
        }
        else if(mArrangeType == ListItemArrangeType.BottomToTop)
        {
            float pos = 0;
            if (mSupportScrollBar)
            {
                pos = GetItemPos(mItemList[0].ItemIndex);
            }
            float pos1 = mItemList[0].CachedRectTransform.localPosition.y;
            float d = pos - pos1;
            float curY = pos;
            for (int i = 0; i < count; ++i)
            {
                LoopListViewItem2 item = mItemList[i];
                item.CachedRectTransform.localPosition = new Vector3(item.StartPosOffset, curY, 0);
                curY = curY + item.CachedRectTransform.rect.height + item.Padding;
            }
            if(d != 0)
            {
                Vector3 p = mContainerTrans.localPosition;
                p.y = p.y - d;
                mContainerTrans.localPosition = p;
            }
        }
        else if (mArrangeType == ListItemArrangeType.LeftToRight)
        {
            float pos = 0;
            if (mSupportScrollBar)
            {
                pos = GetItemPos(mItemList[0].ItemIndex);
            }
            float pos1 = mItemList[0].CachedRectTransform.localPosition.x;
            float d = pos - pos1;
            float curX = pos;
            for (int i = 0; i < count; ++i)
            {
                LoopListViewItem2 item = mItemList[i];
                item.CachedRectTransform.localPosition = new Vector3(curX, item.StartPosOffset, 0);
                curX = curX + item.CachedRectTransform.rect.width + item.Padding;
            }
            if (d != 0)
            {
                Vector3 p = mContainerTrans.localPosition;
                p.x = p.x - d;
                mContainerTrans.localPosition = p;
            }

        }
        else if (mArrangeType == ListItemArrangeType.RightToLeft)
        {
            float pos = 0;
            if (mSupportScrollBar)
            {
                pos = -GetItemPos(mItemList[0].ItemIndex);
            }
            float pos1 = mItemList[0].CachedRectTransform.localPosition.x;
            float d = pos - pos1;
            float curX = pos;
            for (int i = 0; i < count; ++i)
            {
                LoopListViewItem2 item = mItemList[i];
                item.CachedRectTransform.localPosition = new Vector3(curX, item.StartPosOffset, 0);
                curX = curX - item.CachedRectTransform.rect.width - item.Padding;
            }
            if (d != 0)
            {
                Vector3 p = mContainerTrans.localPosition;
                p.x = p.x - d;
                mContainerTrans.localPosition = p;
            }

        }
        if (mIsDraging)
        {
            mScrollRect.OnBeginDrag(mPointerEventData);
            mScrollRect.Rebuild(CanvasUpdate.PostLayout);
            mScrollRect.velocity = mAdjustedVec;
            mNeedAdjustVec = true;
        }
    }
    void UpdateContentSize()
    {
        float size = GetContentPanelSize();
        if (mIsVertList)
        {
            if(mContainerTrans.rect.height != size)
            {
                mContainerTrans.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, size);
            }
        }
        else
        {
            if(mContainerTrans.rect.width != size)
            {
                mContainerTrans.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, size);
            }
        }
    }
}

}

推荐阅读更多精彩内容