ScrollView无线列表

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;
using UnityEngine.EventSystems;
[DisallowMultipleComponent]
public class UIWarpContent : MonoBehaviour
{

    public delegate void OnInitializeItem(GameObject go, int dataIndex);

    public OnInitializeItem onInitializeItem;

    public delegate void OnInitializeItem1(Item item, int dataIndex);

    public OnInitializeItem1 onInitializeItem1;

    public enum Arrangement
    {
        Horizontal,
        Vertical,
    }

    /// <summary>
    /// Type of arrangement -- vertical or horizontal.
    /// </summary>

    public Arrangement arrangement = Arrangement.Vertical;

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

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

    public float cellWidth = 200f;

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

    public float cellHeight = 200f;

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

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


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

    public ScrollRect scrollRect;

    public RectTransform content;

    public GameObject goItemPrefab;

    private int dataCount;

    private int curScrollPerLineIndex = -1;

    private List<UIWarpContentItem> listItem = new List<UIWarpContentItem>();

    private Queue<UIWarpContentItem> unUseItem = new Queue<UIWarpContentItem>();

    public void Init(int dataCount)
    {

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

        }
        setDataCount(dataCount);
        if (null != unUseItem) unUseItem.Clear();
        if (null != listItem) listItem.Clear();

        setUpdateRectItem(0);
    }

    public void RushData(int dataCount)
    {
        scrollRect.onValueChanged.RemoveAllListeners();
        if (listItem.Count > 0)
        {
            for (int i = listItem.Count - 1; i >= 0; i--)
            {
                UIWarpContentItem item = listItem[i];
                item.Index = -10;
                listItem.Remove(item);
                unUseItem.Enqueue(item);
            }
        } 
        if (dataCount > 0)
        {
            scrollRect.onValueChanged.AddListener(onValueChanged);
        }
        setDataCount(dataCount);
        setUpdateRectItem(0);
    }
    public void ShowItem(int count)
    {
        if (arrangement == Arrangement.Vertical)
        {
            content.anchoredPosition = new Vector2(0, count * cellHeight);
        }
        else
        {
            content.anchoredPosition = new Vector2(count * cellWidth, 0);
        }
    }
    public void setDataCount(int count)
    {
        if (dataCount == count)
        {
            return;
        }
        dataCount = count;
        setUpdateContentSize();
    }
    private void onValueChanged(Vector2 vt2)
    {
        switch (arrangement)
        {
            case Arrangement.Vertical:
                float y = vt2.y;
                if (y >= 1.0f || y <= 0.0f)
                {

                    //                return;
                }
                break;
            case Arrangement.Horizontal:
                float x = vt2.x;
                if (x <= 0.0f || x >= 1.0f)
                {
                    return;
                }
                break;
        }
        int _curScrollPerLineIndex = getCurScrollPerLineIndex();
        if (_curScrollPerLineIndex == curScrollPerLineIndex)
        {
            return;
        }
        setUpdateRectItem(_curScrollPerLineIndex);
    }

    /**
     * @des:设置更新区域内item
     * 功能:
     * 1.隐藏区域之外对象      
     * 2.更新区域内数据
     */
    private void setUpdateRectItem(int scrollPerLineIndex)
    {
        if (scrollPerLineIndex < 0)
        {
            return;
        }
        curScrollPerLineIndex = scrollPerLineIndex;
        int startDataIndex = curScrollPerLineIndex * maxPerLine;
        int endDataIndex = (curScrollPerLineIndex + viewCount) * maxPerLine;
        if (listItem == null)
        {
            return;
        }
        //移除
        for (int i = listItem.Count - 1; i >= 0; i--)
        {
            UIWarpContentItem item = listItem[i];
            int index = item.Index;
            if (index < startDataIndex || index >= endDataIndex)
            {
                item.Index = -10;
                listItem.Remove(item);
                unUseItem.Enqueue(item);
            }

        }
        //显示
        for (int dataIndex = startDataIndex; dataIndex < endDataIndex; dataIndex++)
        {
            if (dataIndex >= dataCount)
            {
                continue;
            }
            if (isExistDataByDataIndex(dataIndex))
            {
                continue;
            }
            createItem(dataIndex);
        }
    }
    public float getViewItemSize
    { 
        get
        {
            return cellHeight + cellHeightSpace;

        }
    }
    public void UpdateViewCount(int count)
    {
        viewCount = count;
        setUpdateRectItem(viewCount);
    }


    /**
     * @des:添加当前数据索引数据
     */
    public void AddItem(int dataIndex)
    {
        if (dataIndex < 0 || dataIndex > dataCount)
        {
            Debug.Log("过滤了!" + "dataIndex = " + dataIndex + " | dataCount = " + dataCount);
            return;
        }
        //检测是否需添加gameObject
        bool isNeedAdd = false;
        for (int i = listItem.Count - 1; i >= 0; i--)
        {
            UIWarpContentItem item = listItem[i];
            if (item.Index >= (dataCount - 1))
            {
                isNeedAdd = true;
                break;
            }
        }
        setDataCount(dataCount + 1);
        if (isNeedAdd)
        {
            for (int i = 0; i < listItem.Count; i++)
            {
                UIWarpContentItem item = listItem[i];
                int oldIndex = item.Index;
                if (oldIndex >= dataIndex)
                {
                    item.Index = oldIndex + 1;
                }
            }
            setUpdateRectItem(getCurScrollPerLineIndex());
        }
        else
        {
            //重新刷新数据
            //for (int i = 0; i < listItem.Count; i++) {
            //    UIWarpContentItem item = listItem [i];
            //    int oldIndex = item.Index;
            //    if (oldIndex>=dataIndex) {
            //        item.Index = oldIndex;
            //    }
            //    item = null;
            //}
        }

    }
    /**
     * @des:添加当前数据索引数据
     */
    public void UpdataItem(int dataIndex)
    {
        if (dataIndex < 0 || dataIndex > dataCount)
        {
            return;
        }
        if (isExistDataByDataIndex(dataIndex))
        {
            for (int i = 0; i < listItem.Count; i++)
            {
                if (listItem[i].Index == dataIndex)
                {
                    listItem[i].Index = dataIndex;
                    break;
                }
            }
        }
    }
    public UIWarpContentItem GetItem(int dataIndex)
    {
        if (dataIndex < 0 || dataIndex > dataCount)
        {
            return null;
        }
        if (isExistDataByDataIndex(dataIndex))
        {
            //            UIWarpContentItem go = new UIWarpContentItem ();
            for (int i = 0; i < listItem.Count; i++)
            {
                if (listItem[i].Index == dataIndex)
                {
                    return listItem[i];
                }
            }
        }
        return null;
    }
    public void UpdataAllItem()
    {

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

        bool isNeedDestroyGameObject = (listItem.Count >= dataCount);
        setDataCount(dataCount - 1);

        for (int i = listItem.Count - 1; i >= 0; i--)
        {
            UIWarpContentItem item = listItem[i];
            int oldIndex = item.Index;
            if (oldIndex == dataIndex)
            {
                listItem.Remove(item);
                if (isNeedDestroyGameObject)
                {
                    Destroy(item.gameObject);
                }
                else
                {
                    item.Index = -1;
                    unUseItem.Enqueue(item);
                }
            }
            if (oldIndex > dataIndex)
            {
                item.Index = oldIndex - 1;
            }
        }
        setUpdateRectItem(getCurScrollPerLineIndex());
        if (unUseItem.Count > 0)
        {
            UIWarpContentItem item = unUseItem.Dequeue();
            Destroy(item.gameObject);
        }
    }


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

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

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


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

                count = Mathf.FloorToInt(Mathf.Abs(content.anchoredPosition.y) / (cellHeight + cellHeightSpace));
                if (count < 0)
                {
                    count = 0;
                }
                else if (count > dataCount)
                {
                    count = dataCount;
                }
                //            return Mathf.FloorToInt(Mathf.Abs(content.anchoredPosition.y)/(cellHeight+cellHeightSpace));
                return count;
        }
        return 0;
    }

    /**
     * @des:更新Content SizeDelta
     */
    private void setUpdateContentSize()
    {
        int lineCount = Mathf.CeilToInt((float)dataCount / maxPerLine);
        switch (arrangement)
        {
            case Arrangement.Horizontal:
                content.sizeDelta = new Vector2(cellWidth * lineCount + cellWidthSpace * (lineCount - 1), content.sizeDelta.y);
                break;
            case Arrangement.Vertical:
                content.sizeDelta = new Vector2(content.sizeDelta.x, cellHeight * lineCount + cellHeightSpace * (lineCount - 1));
                break;
        }
    }
    private RectTransform _rectTransform;
    private RectTransform rectTransform
    {
        get
        {
            if (_rectTransform == null)
            {
                _rectTransform = scrollRect.GetComponent<RectTransform>();

            }
            return _rectTransform;
        }
    }
    /**
     * @des:实例化预设对象 、添加实例化对象到指定的子对象下
     */
    private GameObject addChild(GameObject goPrefab, Transform parent)
    {
        if (goPrefab == null || parent == null)
        {
            Debug.LogError("异常。UIWarpContent.cs addChild(goPrefab = null  || parent = null)");
            return null;
        }
        GameObject goChild = Instantiate(goPrefab);
        goChild.layer = parent.gameObject.layer;
        goChild.transform.SetParent(parent, false);
        if (maxPerLine <= 1)
        {

            switch (arrangement)
            {
                case Arrangement.Horizontal:
                    goChild.transform.GetComponent<RectTransform>().sizeDelta = new Vector2(goChild.transform.GetComponent<RectTransform>().rect.width, rectTransform.rect.height);
                    break;
                case Arrangement.Vertical:
                    goChild.transform.GetComponent<RectTransform>().sizeDelta = new Vector2(cellWidth, cellHeight);
                    break;
            }
        }
        goChild.gameObject.SetActive(true);

        return goChild;
    }
    public void ClearAllData()
    {
        scrollRect.onValueChanged.RemoveAllListeners();
        if (listItem != null && listItem.Count > 0)
        {
            foreach (var item in listItem)
            {
                Destroy(item.gameObject);
            }
            //foreach (var item in unUseItem)
            //{
            //    GameObject go = item.gameObject;
            //    Destroy(go);
            //}
            listItem.Clear();
            if (null != unUseItem)
            {
                unUseItem.Clear();
            }

            onInitializeItem = null;
            //重置上一次的操作位置
            if (null != scrollRect.verticalScrollbar)
            {
                scrollRect.verticalScrollbar.value = 1;
            }
            //重置上一次的操作位置
            if (null != scrollRect.horizontalScrollbar)
            {
                scrollRect.horizontalScrollbar.value = 1;
                content.anchoredPosition = Vector2.zero;
            }

        }
        if (content != null)
        {
            int childCount = content.transform.childCount;
            for (int i = 0; i < childCount; i++)
            {
                Destroy(content.transform.GetChild(i).gameObject);
            }

        }
    }
    void OnDestroy()
    {

        scrollRect = null;
        content = null;
        goItemPrefab = null;
        onInitializeItem = null;

        listItem.Clear();
        unUseItem.Clear();
    }
}

using UnityEngine;
using System.Collections;
/***
 *@des:warp下Element对应标记
 */
[DisallowMultipleComponent]
public class UIWarpContentItem : MonoBehaviour {

    private int index;
    private UIWarpContent warpContent;


    private RectTransform mtransform;

    private RectTransform mYtransform {

        get
        {
            if (mtransform == null)
            {
                mtransform = transform.GetComponent<RectTransform>();
            }
            return mtransform;
        }
    }

    void OnDestroy(){
        warpContent = null;
    }

    public UIWarpContent WarpContent{
        set{ 
            warpContent = value;
        }
    }
    public string getName()
    {
        return gameObject.name;
    }
    private Item item;
    public Item getItem()
    {
        if (item == null)
            item  = gameObject.GetComponent<Item>();    
        return item;
    }
    public int Index {
        set{
            index = value; 
            mYtransform.localPosition = warpContent.getLocalPositionByIndex(index);
            gameObject.name = index.ToString(); 
                //(index<10)?("0"+index):(""+index);
            if (warpContent.onInitializeItem1 != null && index>=0) {
                warpContent.onInitializeItem1 (getItem(), index);
                //Debug.Log("index = " + index);
            }
        }
        get{ 
            return index;
        }
    }
}
 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值