ScrollView 最优使用方案

发表于2017-12-11
评论0 1.5k浏览
ScrollView 一直是UI界面里最难厉害的,这里的解决方案可谓是集对象池,自定义各种效果等之大乘。代码很长,但有demo可以观摩。

这个小插件的借助了 Grid Layout Group组件的各个参数,利用拖动事件驱动所有的滑动效果。
自动控制ScrollView下的Item对象,利用对象池技术,最优化实现滚动显示信息的功能。

详细使用方法请看源代码:
using System;  
using System.Collections;  
using System.Collections.Generic;  
using UnityEngine;  
using UnityEngine.EventSystems;  
using UnityEngine.UI;  
/// <summary>  
/// 控制类  
/// </summary>  
public class ScrollRectAutoItem : MonoBehaviour, IEndDragHandler, IDragHandler  
{  
    /// <summary>  
    /// 拖拽事件回调  
    /// </summary>  
    public Action<float, float> OnDragBack;  
    /// <summary>  
    /// 拖拽事件回调  
    /// </summary>  
    public Action<float, float> OnEndDragBack;  
    /// <summary>  
    /// 滚动事件回调  
    /// </summary>  
    public Action<float, float> ScrollItemBack;  
    /// <summary>  
    /// Item控制模式  
    /// </summary>  
    public ItemState ItemState = ItemState.RollItem;  
    /// <summary>  
    /// 组件  
    /// </summary>  
    private ScrollRect customScrollRect;  
    private RectTransform content;  
    private GridLayoutGroup gridLayoutGroup;  
    /// <summary>  
    /// item预置物  
    /// </summary>  
    private GameObject itemUnit;  
    /// <summary>  
    /// item预置物路径  
    /// </summary>  
    private string itemUnitPath;  
    /// <summary>  
    /// Item对象池  
    /// </summary>  
    private GameObject pool;  
    /// <summary>  
    /// 当前滑动的区域id  
    /// </summary>  
    private float itemIdFloatDown = 0;  
    private float itemIdFloatUp = 0;  
    private int itemIdIntDown = 0;  
    private int itemIdIntUp = 0;  
    /// <summary>  
    /// customScrollRect数据  
    /// </summary>  
    private Vector2 sizeDelta;  
    /// <summary>  
    /// content数据  
    /// </summary>  
    private Vector3 contentLocalPos;  
    /// <summary>  
    /// GridLayoutGroup数据  
    /// </summary>  
    private int constraintCount = 0;  
    private Vector2 cellSize = Vector2.zero;  
    private Vector2 spacing = Vector2.zero;  
    private RectOffset padding;  
    /// <summary>  
    /// 子对象个数  
    /// </summary>  
    private int childCount;  
    /// <summary>  
    /// 子对象行数或者列数  
    /// </summary>  
    private int rowOrColNum;  
    /// <summary>  
    /// 每一个item的位置  
    /// </summary>  
    private Dictionary<int, Vector3> itemPosDic;  
    /// <summary>  
    /// 维护子对象的使用  
    /// </summary>  
    private Stack<GameObject> itemStack;  
    /// <summary>  
    /// item信息类  
    /// </summary>  
    private Type handlerInfo;  
    /// <summary>  
    /// 参数  
    /// </summary>  
    private List<object> parList;  
    /// <summary>  
    /// 参数类型  
    /// </summary>  
    private Type paramType = null;  
    /// <summary>  
    /// Item的信息类集合  
    /// </summary>  
    private Dictionary<int, ABaseItemHandler> handlerInfoDic;  
    //缓存---用于滚动优化  
    private int itemIdIntDownCache = -1;  
    private int itemIdIntUpCache = -1;  
    private int childCountCache = -1;  
    private int toItemId = -1;  
    /// <summary>  
    /// 锁  
    /// </summary>  
    private System.Object thisLock = new System.Object();  
    /// <summary>  
    /// 点击Item移动结束事件回调  
    /// </summary>  
    private Action<int> MoveToItenIdBack;  
    private void Awake()  
    {  
        //获取组件  
        customScrollRect = this.transform.GetComponent<ScrollRect>();  
        content = this.transform.FindChild("Content").GetComponent<RectTransform>();  
        gridLayoutGroup = content.GetComponent<GridLayoutGroup>();  
        //获取Item池子  
        Transform poolTrans = this.transform.FindChild("Pool");  
        if (poolTrans == null)  
        {  
            poolTrans = new GameObject("Pool").GetComponent<Transform>();  
            poolTrans.SetParent(this.transform);  
            initGameObj(poolTrans.gameObject);  
        }  
        pool = poolTrans.gameObject;  
        //设置滑动方向  
        if (gridLayoutGroup.constraint == GridLayoutGroup.Constraint.FixedColumnCount)  
        {  
            customScrollRect.vertical = true;  
            customScrollRect.horizontal = false;  
        }  
        else if (gridLayoutGroup.constraint == GridLayoutGroup.Constraint.FixedRowCount)  
        {  
            customScrollRect.vertical = false;  
            customScrollRect.horizontal = true;  
        }  
        else  
        {  
            customScrollRect.vertical = true;  
            customScrollRect.horizontal = true;  
        }  
        //获取customScrollRect数据  
        sizeDelta = customScrollRect.GetComponent<RectTransform>().sizeDelta;  
        //设置滑动回调事件  
        customScrollRect.onValueChanged.AddListener(ScrollRectEvent);  
        customScrollRect.decelerationRate = 0.001f;  
        //记录content数据  
        contentLocalPos = content.localPosition;  
        UIHelper.ClearChildObj(content.transform);  
        //获取GridLayoutGroup数据  
        constraintCount = gridLayoutGroup.constraintCount;  
        cellSize = gridLayoutGroup.cellSize;  
        spacing = gridLayoutGroup.spacing;  
        padding = gridLayoutGroup.padding;  
        //禁用  
        ContentSizeFitter sizeFitter = content.GetComponent<ContentSizeFitter>();  
        if (sizeFitter != null)  
        {  
            sizeFitter.enabled = false;  
        }  
        gridLayoutGroup.enabled = false;  
        //item挂载的信息类  
        handlerInfoDic = new Dictionary<int, ABaseItemHandler>();  
        //初始栈空间  
        itemStack = new Stack<GameObject>();  
    }  
    /// <summary>  
    /// 设置惯性  
    /// </summary>  
    public void SetInertia(bool boo)  
    {  
        if (customScrollRect != null)  
        {  
            customScrollRect.inertia = boo;  
        }  
    }  
    /// <summary>  
    /// 根据子对象的数量初始化  
    /// </summary>  
    /// <param name="itemPath">子对象预置物路径</param>  
    /// <param name="childCount">子对象数量</param>  
    /// <param name="type">脚本</param>  
    /// <param name="parList">参数</param>  
    public void Init(string itemPath, int childCount, Type type)  
    {  
        Init<object>(itemPath, childCount, type, null);  
    }  
    /// <summary>  
    /// 根据子对象的数量初始化  
    /// </summary>  
    /// <param name="itemPath">子对象预置物路径</param>  
    /// <param name="childCount">子对象数量</param>  
    /// <param name="type">脚本</param>  
    /// <param name="parList">参数</param>  
    public void Init<T>(string itemPath, int childCount, Type type, List<T> pList = null)  
    {  
        //item预置物 得到的是一个引用,非实例化  
        this.itemUnitPath = itemPath;  
        itemUnit = Resources.Load(itemPath) as GameObject;  
        Init<T>(itemUnit, childCount, type, pList);  
    }  
    /// <summary>  
    /// 根据子对象的数量初始化  
    /// </summary>  
    /// <param name="itemPath">子对象预置物路径</param>  
    /// <param name="childCount">子对象数量</param>  
    /// <param name="type">脚本</param>  
    /// <param name="parList">参数</param>  
    public void Init<T>(GameObject item, int childCount, Type type, List<T> pList = null)  
    {  
        //子对象个数  
        this.childCount = childCount;  
        //参数集合  
        if (pList != null)  
        {  
            this.parList = new List<object>();  
            for (int i = 0; i < pList.Count; i++)  
            {  
                this.parList.Add(pList[i]);  
            }  
            this.paramType = typeof(T);  
        }  
        else  
        {  
            this.parList = null;  
        }  
        //子对象  
        itemUnit = item;  
        //item挂载的信息类  
        handlerInfo = type;  
        handlerInfoDic.Clear();  
        //设置Content宽高  
        float width = 0;  
        float height = 0;  
        rowOrColNum = 0;  
        if (gridLayoutGroup.constraint == GridLayoutGroup.Constraint.FixedColumnCount)  
        {  
            rowOrColNum = childCount / constraintCount;  
            rowOrColNum = (childCount % gridLayoutGroup.constraintCount == 0) ? rowOrColNum : rowOrColNum + 1;  
            height = rowOrColNum * cellSize.y + (rowOrColNum - 1) * spacing.y + padding.top + padding.bottom;  
            width = constraintCount * cellSize.x + (constraintCount - 1) * spacing.x + padding.left + padding.right;  
        }  
        else if (gridLayoutGroup.constraint == GridLayoutGroup.Constraint.FixedRowCount)  
        {  
            rowOrColNum = childCount / constraintCount;  
            rowOrColNum = (childCount % gridLayoutGroup.constraintCount == 0) ? rowOrColNum : rowOrColNum + 1;  
            width = rowOrColNum * cellSize.x + (rowOrColNum - 1) * spacing.x + padding.left + padding.right;  
            height = constraintCount * cellSize.y + (constraintCount - 1) * spacing.y + padding.top + padding.bottom;  
        }  
        else  
        {  
            return;  
        }  
        content.sizeDelta = new Vector2(width, height);  
        //记录每一个item的位置  
        itemPosDic = new Dictionary<int, Vector3>();  
        Vector3 pos = Vector3.zero;  
        Vector3 paddingV2 = new Vector3(cellSize.x / 2 + padding.left, -1f * cellSize.y / 2 - padding.top, 0);  
        if (gridLayoutGroup.constraint == GridLayoutGroup.Constraint.FixedColumnCount)  
        {  
            for (int i = 0; i < rowOrColNum; i++)  
            {  
                for (int j = 0; j < constraintCount; j++)  
                {  
                    pos = new Vector3(cellSize.x * j, -1f * cellSize.y * i, 0) + paddingV2;  
                    itemPosDic.Add(i * constraintCount + j, pos);  
                }  
            }  
        }  
        else if (gridLayoutGroup.constraint == GridLayoutGroup.Constraint.FixedRowCount)  
        {  
            for (int i = 0; i < rowOrColNum; i++)  
            {  
                for (int j = 0; j < constraintCount; j++)  
                {  
                    pos = new Vector3(cellSize.x * i, -1f * cellSize.y * j, 0) + paddingV2;  
                    itemPosDic.Add(i * constraintCount + j, pos);  
                }  
            }  
        }  
        else  
        {  
            return;  
        }  
        //实例化Item  
        if (ItemState == ItemState.RollItem)  
        {  
            this.InitRollItem();  
        }  
        else if (ItemState == ItemState.HideItem)  
        {  
            this.InitHideItem();  
        }  
    }  
    /// <summary>  
    /// 初始化Item  
    /// </summary>  
    private void InitRollItem()  
    {  
        //初始栈空间  
        int initNum = 0;  
        if (gridLayoutGroup.constraint == GridLayoutGroup.Constraint.FixedColumnCount)  
        {  
            initNum = ((int)(sizeDelta.y / cellSize.y) + 1) * constraintCount;  
        }  
        else if (gridLayoutGroup.constraint == GridLayoutGroup.Constraint.FixedRowCount)  
        {  
            initNum = ((int)(sizeDelta.x / cellSize.x) + 1) * constraintCount;  
        }  
        else  
        {  
            return;  
        }  
        initNum = initNum > childCount ? childCount : initNum;  
        //初始化item显示信息  
        ItemStackClear();  
        if (childCountCache != childCount)  
        {  
            this.childCountCache = childCount;  
            InitContent(initNum);  
        }  
        else  
        {  
            UpdataItem();  
        }  
    }  
    /// <summary>  
    /// 初始化Item  
    /// </summary>  
    private void InitHideItem()  
    {  
        UIHelper.CreateChildIcon(this.childCount, content, this.itemUnitPath);  
        GameObject go = null;  
        for (int i = 0; i < this.childCount; i++)  
        {  
            go = content.transform.GetChild(i).gameObject;  
            go.transform.localPosition = itemPosDic[i];  
            go.transform.localScale = Vector3.one;  
            go.name = i.ToString();  
            var handler = go.GetComponent<ABaseItemHandler>();  
            if (handler == null)  
            {  
                handler = go.AddComponent(handlerInfo) as ABaseItemHandler;  
                handler.Init();  
                handler.ParamType = this.paramType;  
            }  
            if (this.parList != null)  
            {  
                handler.Show(i, this.parList[i]);  
            }  
            else  
            {  
                handler.Show(i);  
            }  
            handler.OriginalPos = itemPosDic[i];  
            if (!handlerInfoDic.ContainsKey(i))  
            {  
                handlerInfoDic.Add(i, handler);  
            }  
            else  
            {  
                handlerInfoDic[i] = handler;  
            }  
        }  
        //模拟滚动回调 获取上下边界点  
        ScrollRectEvent(Vector2.zero);  
        int id = (itemIdIntUp - 1) * constraintCount;  
        if (id > 0 && childCount > id)  
        {  
            for (int i = 0; i < id; i++)  
            {  
                handlerInfoDic[i].ItemTrans.gameObject.SetActive(false);  
            }  
        }  
        id = (itemIdIntDown + 1) * constraintCount;  
        if (id > 0 && childCount > id)  
        {  
            for (int i = id; i < childCount; i++)  
            {  
                handlerInfoDic[i].ItemTrans.gameObject.SetActive(false);  
            }  
        }  
    }  
    /// <summary>  
    /// 初始化Content  
    /// </summary>  
    /// <param name="num"></param>  
    private void InitContent(int num)  
    {  
        UIHelper.ClearChildObj(content);  
        for (int i = 0; i < num; i++)  
        {  
            PopStack(i);  
        }  
    }  
    /// <summary>  
    /// 更新界面信息  
    /// </summary>  
    public void UpdataItem()  
    {  
        ABaseItemHandler handler = null;  
        for (int i = 0; i < content.transform.childCount; i++)  
        {  
            handler = content.transform.GetChild(i).GetComponent<ABaseItemHandler>();  
            if (handler != null)  
            {  
                if (this.parList != null)  
                {  
                    handler.Show(handler.ItemId, this.parList[handler.ItemId]);  
                }  
                else  
                {  
                    handler.Show(handler.ItemId);  
                }  
            }  
            else  
            {  
                this.childCountCache = -1;  
                InitRollItem();  
                return;  
            }  
            if (!handlerInfoDic.ContainsValue(handler))  
            {  
                handlerInfoDic.Add(handler.ItemId, handler);  
            }  
        }  
    }  
    /// <summary>  
    /// 拖动回调事件  
    /// </summary>  
    /// <param name="v2"></param>  
    private void ScrollRectEvent(Vector2 v2)  
    {  
        //定位上下两个边界点  
        if (customScrollRect.horizontal)  
        {  
            itemIdFloatDown = (-1f * content.localPosition.x + sizeDelta.x / 2 - padding.left) / cellSize.x;  
            itemIdFloatUp = -1f * (content.localPosition.x - contentLocalPos.x + padding.left) / cellSize.x;  
        }  
        else if (customScrollRect.vertical)  
        {  
            itemIdFloatDown = (content.localPosition.y + sizeDelta.y / 2 + padding.top) / cellSize.y;  
            itemIdFloatUp = (content.localPosition.y - contentLocalPos.y - padding.top) / cellSize.y;  
        }  
        else  
        {  
            return;  
        }  
        //控制边界  
        itemIdFloatDown = itemIdFloatDown < 0 ? 0 : itemIdFloatDown;  
        itemIdFloatUp = itemIdFloatUp < 0 ? 0 : itemIdFloatUp;  
        //回调---实现自由控制item变化  
        if (ScrollItemBack != null)  
        {  
            ScrollItemBack.Invoke(itemIdFloatUp, itemIdFloatDown);  
        }  
        itemIdIntDown = GetIntValue(itemIdFloatDown);  
        itemIdIntUp = GetIntValue(itemIdFloatUp);  
        //Debug.Log("itemIdIntDown   " + itemIdIntDown * constraintCount);  
        //Debug.Log("itemIdIntUp   " + itemIdIntUp * constraintCount);  
        //优化效率问题  
        if (itemIdIntDownCache != itemIdIntDown || itemIdIntUpCache != itemIdIntUp)  
        {  
            this.ControlBound();  
            itemIdIntDownCache = itemIdIntDown;  
            itemIdIntUpCache = itemIdIntUp;  
        }  
    }  
    /// <summary>  
    /// 边界控制  
    /// </summary>  
    private void ControlBound()  
    {  
        //临时变量  
        Transform transItem = null;  
        int id = 0;  
        for (int i = 0; i < constraintCount; i++)  
        {  
            //上  
            id = (itemIdIntUp - 1) * constraintCount + i;  
            if (id >= 0 && childCount > id)  
            {  
                transItem = content.FindChild(id.ToString());  
                if (transItem != null)  
                {  
                    if (ItemState == ItemState.RollItem)  
                    {  
                        PushStack(transItem.gameObject);        //进栈  
                    }  
                    else if (ItemState == ItemState.HideItem)  
                    {  
                        SetActive(transItem.gameObject, false);  
                    }  
                }  
            }  
            id = itemIdIntUp * constraintCount + i;  
            if (id >= 0 && childCount > id)  
            {  
                transItem = content.FindChild(id.ToString());  
                if (transItem == null)  
                {  
                    if (ItemState == ItemState.RollItem)  
                    {  
                        PopStack(id);                           //出栈  
                    }  
                }  
                else  
                {  
                    if (ItemState == ItemState.HideItem)  
                    {  
                        SetActive(transItem.gameObject, true);  
                    }  
                }  
            }  
            //下  
            id = itemIdIntDown * constraintCount + i;  
            if (id >= 0 && childCount > id)  
            {  
                transItem = content.FindChild(id.ToString());  
                if (transItem == null)  
                {  
                    if (ItemState == ItemState.RollItem)  
                    {  
                        PopStack(id);                           //出栈  
                    }  
                }  
                else  
                {  
                    if (ItemState == ItemState.HideItem)  
                    {  
                        SetActive(transItem.gameObject, true);  
                    }  
                }  
            }  
            id = (itemIdIntDown + 1) * constraintCount + i;  
            if (id >= 0 && childCount > id)  
            {  
                transItem = content.FindChild(id.ToString());  
                if (transItem != null)  
                {  
                    if (ItemState == ItemState.RollItem)  
                    {  
                        PushStack(transItem.gameObject);        //进栈  
                    }  
                    else if (ItemState == ItemState.HideItem)  
                    {  
                        SetActive(transItem.gameObject, false);  
                    }  
                }  
            }  
        }  
    }  
    /// <summary>  
    /// 初始化num个子对象放进栈里面  
    /// </summary>  
    /// <param name="num"></param>  
    private void InitStack(int num)  
    {  
        GameObject obj = Instantiate<GameObject>(itemUnit);  
        PushStack(obj);  
    }  
    /// <summary>  
    /// 进栈维护  
    /// </summary>  
    /// <param name="go"></param>  
    private void PushStack(GameObject obj)  
    {  
        if (obj == null)  
        {  
            return;  
        }  
        lock (this.thisLock)  
        {  
            obj.transform.SetParent(pool.transform);  
            initGameObj(obj);  
            obj.SetActive(false);  
            itemStack.Push(obj);  
            //移除信息类  
            RemoveItemInfo(obj);  
        }  
    }  
    /// <summary>  
    /// 出栈维护  
    /// </summary>  
    /// <returns></returns>  
    private GameObject PopStack(int itemId)  
    {  
        GameObject obj = null;  
        if (itemStack.Count == 0)  
        {  
            obj = Instantiate<GameObject>(itemUnit);  
            initGameObj(obj);  
        }  
        else  
        {  
            lock (this.thisLock)  
            {  
                obj = itemStack.Pop();  
            }  
        }  
        obj.transform.SetParent(content);  
        obj.transform.localPosition = itemPosDic[itemId];  
        obj.transform.localScale = Vector3.one;  
        obj.name = itemId.ToString();  
        obj.SetActive(true);  
        //挂载信息类  
        AddItemInfo(obj, itemId);  
        return obj;  
    }  
    /// <summary>  
    /// 删除栈里面的元素  
    /// </summary>  
    /// <param name="go"></param>  
    private void DelectStackItem(int num)  
    {  
        for (int i = 0; i < num; i++)  
        {  
            lock (this.thisLock)  
            {  
                GameObject obj = itemStack.Pop();  
                GameObject.Destroy(obj);  
            }  
        }  
    }  
    /// <summary>  
    /// 清理栈空间  
    /// </summary>  
    private void ItemStackClear()  
    {  
        if (itemStack.Count > 0)  
        {  
            for (int i = 0; i < itemStack.Count; i++)  
            {  
                GameObject go = itemStack.Pop();  
                GameObject.Destroy(go);  
            }  
        }  
        UIHelper.ClearChildObj(pool.transform);  
    }  
    /// <summary>  
    /// 挂载Item信息类  
    /// </summary>  
    /// <param name="go"></param>  
    /// <param name="itemId"></param>  
    private void AddItemInfo(GameObject go, int itemId)  
    {  
        ABaseItemHandler handler = go.GetComponent<ABaseItemHandler>();  
        if (handler == null)  
        {  
            handler = go.AddComponent(handlerInfo) as ABaseItemHandler;//待修改  
            handler.Init();  
            handler.ParamType = this.paramType;  
        }  
        if (this.parList == null)  
        {  
            handler.Show(itemId);  
        }  
        else  
        {  
            if (this.parList.Count > itemId)  
            {  
                handler.Show(itemId, this.parList[itemId]);  
            }  
        }  
        if (!handlerInfoDic.ContainsKey(itemId))  
        {  
            handlerInfoDic.Add(itemId, handler);  
        }  
        else  
        {  
            handlerInfoDic[itemId] = handler;  
        }  
    }  
    /// <summary>  
    /// 移除Item信息类  
    /// </summary>  
    /// <param name="go"></param>  
    private void RemoveItemInfo(GameObject go)  
    {  
        ABaseItemHandler handler = go.GetComponent<ABaseItemHandler>();  
        if (handler != null)  
        {  
            handlerInfoDic.Remove(handler.ItemId);  
        }  
    }  
    /// <summary>  
    /// 获取Item信息类  
    /// </summary>  
    /// <param name="itemId"></param>  
    /// <returns></returns>  
    public ABaseItemHandler GetHandler(int itemId)  
    {  
        ABaseItemHandler handler = null;  
        if (!handlerInfoDic.TryGetValue(itemId, out handler))  
        {  
            Debug.Log("未能找到id=" + itemId + " 的信息类");  
        }  
        return handler;  
    }  
    /// <summary>  
    /// 拖拽中  
    /// </summary>  
    /// <param name="eventData"></param>  
    public void OnDrag(PointerEventData eventData)  
    {  
        if (this.OnDragBack != null)  
        {  
            this.OnDragBack.Invoke(itemIdFloatUp, itemIdFloatDown);  
        }  
    }  
    /// <summary>  
    /// 拖拽结束 可以实现自定义Item变化  
    /// </summary>  
    /// <param name="eventData"></param>  
    public void OnEndDrag(PointerEventData eventData)  
    {  
        if (OnEndDragBack != null)  
        {  
            OnEndDragBack.Invoke(itemIdFloatUp, itemIdFloatDown);  
        }  
    }  
    /// <summary>  
    /// 点击移动到Item  
    /// </summary>  
    /// <param name="itemId"></param>  
    /// <param name="call"></param>  
    public void ClickToItem(int itemId, float speed = 500f, Action<int> call = null)  
    {  
        if (toItemId != itemId)  
        {  
            toItemId = itemId;  
            DragToItemId(itemId, speed, call);  
        }  
    }  
    /// <summary>  
    /// 移动到某一个Item  
    /// </summary>  
    /// <param name="itemId"></param>  
    public void DragToItemId(int itemId, float speed = 500f, Action<int> call = null)  
    {  
        this.MoveToItenIdBack = call;  
        Vector3 pos = Vector3.zero;  
        if (customScrollRect.horizontal)  
        {  
            pos = new Vector3(((itemId + 0.5f) * cellSize.x + padding.left) * -1f, content.transform.localPosition.y, 0);  
        }  
        else if (customScrollRect.vertical)  
        {  
            pos = new Vector3(content.transform.localPosition.x, ((itemId + 0.5f) * cellSize.y + padding.top), 0);  
        }  
        Hashtable msg = new Hashtable();  
        msg.Add("position", pos);  
        msg.Add("islocal", true);  
        msg.Add("speed", speed);  
        msg.Add("oncomplete", "MoveStop");  
        msg.Add("oncompletetarget", this.gameObject);  
        msg.Add("oncompleteparams", itemId);  
        msg.Add("easetype", iTween.EaseType.easeOutCubic);  
        iTween.MoveTo(content.gameObject, msg);  
    }  
    /// <summary>  
    /// 移动结束事件  
    /// </summary>  
    private void MoveStop(int itemId)  
    {  
        toItemId = itemId;  
        if (MoveToItenIdBack != null)  
        {  
            MoveToItenIdBack.Invoke(itemId);  
            MoveToItenIdBack = null;  
        }  
    }  
    private int GetIntValue(float value)  
    {  
        int id = Mathf.FloorToInt(value);  
        id = id > rowOrColNum - 1 ? rowOrColNum - 1 : id;  
        id = id < 0 ? 0 : id;  
        return id;  
    }  
    private void initGameObj(GameObject obj)  
    {  
        obj.transform.localPosition = Vector3.zero;  
        obj.transform.localScale = Vector3.one;  
        obj.transform.eulerAngles = Vector3.zero;  
    }  
    private void SetActive(GameObject go, bool boo)  
    {  
        bool bo = go.activeSelf == boo;  
        if (!bo)  
        {  
            go.SetActive(boo);  
        }  
    }  
}  
/// <summary>  
/// Item控制模式  
/// </summary>  
public enum ItemState  
{  
    /// <summary>  
    /// 隐藏模式  
    /// </summary>  
    HideItem,  
    /// <summary>  
    /// 滚动模式  
    /// </summary>  
    RollItem,  
}  
/// <summary>  
/// 约束Item的抽象信息类  
/// </summary>  
public abstract class ABaseItemHandler : MonoBehaviour  
{  
    /// <summary>  
    /// 参数类型  
    /// </summary>  
    public Type ParamType;  
    /// <summary>  
    /// 参数  
    /// </summary>  
    public object Param;  
    /// <summary>  
    /// 原始位置  
    /// </summary>  
    public Vector3 OriginalPos;  
    /// <summary>  
    /// 当前itemId  
    /// </summary>  
    public int ItemId;  
    /// <summary>  
    /// item对象  
    /// </summary>  
    public RectTransform ItemTrans;  
    /// <summary>  
    /// 初始化  
    /// </summary>  
    virtual public void Init()  
    {  
        ItemTrans = this.GetComponent<RectTransform>();  
        OriginalPos = this.ItemTrans.localPosition;  
    }  
    /// <summary>  
    /// 显示信息  
    /// </summary>  
    /// <param name="info"></param>  
    virtual public void Show(int itemId, object e = null)  
    {  
        this.ItemId = itemId;  
        this.Param = e;  
    }  
    /// <summary>  
    /// 修改信息  
    /// </summary>  
    /// <param name="e"></param>  
    virtual public void Modify(object e = null)  
    {  
    }  
    /// <summary>  
    /// 添加事件  
    /// </summary>  
    virtual public void AddEvent()  
    {  
    }  
}  

/// <summary>  
/// UI辅助类  
/// </summary>  
using UnityEngine;  
public class UIHelper  
{  
    /// <summary>  
    /// 创建一定数量的子对象  
    /// </summary>  
    /// <param name="needNum"></param>  
    /// <param name="content"></param>  
    /// <param name="childPath"></param>  
    public static void CreateChildIcon(int needNum, Transform content, string childPath)  
    {  
        //子对象个数  
        int num = content.childCount;  
        if (num > needNum)  
        {  
            for (int i = num - 1; i >= needNum; i--)  
            {  
                GameObject.Destroy(content.GetChild(i).gameObject);  
            }  
        }  
        else  
        {  
            for (int i = num; i < needNum; i++)  
            {  
                GameObject obj = Resources.Load(childPath) as GameObject;  
                obj.transform.SetParent(content);  
                obj.name = i.ToString();  
            }  
        }  
    }  
    /// <summary>  
    /// 清除子对象  
    /// </summary>  
    /// <param name="go"></param>  
    public static void ClearChildObj(Transform go)  
    {  
        for (int i = 0; i < go.childCount; i++)  
        {  
            GameObject obj = go.GetChild(i).gameObject;  
            UnityEngine.Object.Destroy(obj);  
        }  
    }  
}  
详细使用方法,请下载示例代码工程。
链接:http://pan.baidu.com/s/1b9Fm8I 密码:uhxr

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引