zoukankan      html  css  js  c++  java
  • UIGrid/UITable 性能优化

    性能优化

    排行榜,邮件,关卡等数据列表项,一般在玩家打开面板时,都会重新刷新一次数据,那是否有必要每次都生成列表项呢?

    假如每次列表的内容有变动就Instance 新的Gameobject,这是没有必要的浪费。本文想做的就是避免频繁生成新的Gameobject。

    运行效果

    grid_instance

    思路及流程图

    循环利用UIGrid下已有child,改变child的数据(不同child渲染不同的数据)。需要生成时就生成,不需要生成则根据情况显示隐藏

    流程图如下所示

    image

    实现方法

    1、创建工具类:动态生成child ,隐藏多余的child

    2、工具类使用方法:

                        传入template obj(prefab)、data ,ResizeGrid

                        设置每一个Child的内容

    XUIHelper

    public  class XUIHelper
    {
        /// <summary>
        /// 传入指定数量, 对UIGrid里指定数量项SetActive(true)/或创建, 其余的SetActive(false)
        /// 常用于UIGrid下的对象动态增长
        /// </summary>
        public static void ResizeUIGridGameObjects(UIGrid uiGrid, int resizeCount, GameObject templateForNew = null)
        {
            if (templateForNew == null && uiGrid.transform.childCount <= 0)
            {
                CDebug.LogError("template为空  &&  uigrid childCount为0");
                return;
            }
            if (templateForNew == null) templateForNew = uiGrid.transform.GetChild(0).gameObject;
            _ResizeUIWidgetContainerGameObjects(uiGrid.transform, resizeCount, templateForNew);
            uiGrid.Reposition();
        }
    
        public static void ResizeUITableGameObjects(UITable uiTable, int resizeCount, GameObject templateForNew = null)
        {
            if (templateForNew == null && uiTable.transform.childCount <= 0)
            {
                CDebug.LogError("template为空  &&  uigrid childCount为0");
                return;
            }
            if (templateForNew == null) templateForNew = uiTable.transform.GetChild(0).gameObject;
            _ResizeUIWidgetContainerGameObjects(uiTable.transform, resizeCount, templateForNew);
            uiTable.Reposition();
        }
    
        public static void _ResizeUIWidgetContainerGameObjects(Transform transf, int resizeCount, GameObject templateForNew)
        {
            if (templateForNew == null)
                templateForNew = default(GameObject);
    
            for (int i = 0; i < resizeCount; i++)
            {
                GameObject newTemplate = null;
                if (i >= transf.childCount)  //child不足 instantiate
                {
                    newTemplate = Object.Instantiate(templateForNew) as GameObject;
                    newTemplate.transform.parent = transf;
                    ResetLocalTransform(newTemplate.transform);
                }
                newTemplate = transf.GetChild(i).gameObject;
                if (!newTemplate.activeSelf)
                    newTemplate.SetActive(true);
            }
    
            //多余的child setActive(false)
            for (int i = resizeCount; i < transf.childCount; ++i)
            {
                GameObject newTemplate = transf.GetChild(i).gameObject;
                if (newTemplate.activeSelf)
                    newTemplate.SetActive(false);
            }
        }
    
        /// <summary>
        /// 模仿 NGUISelectionTool的同名方法,将位置旋转缩放清零
        /// </summary>
        /// <param name="t"></param>
        public static void ResetLocalTransform(Transform t)
        {
            t.localPosition = Vector3.zero;
            t.localRotation = Quaternion.identity;
            t.localScale = Vector3.one;
        }
    }

    使用方法

    public class XUILevel :CUIController
    {
        private UIGrid LevelGrid;
        private List<CLevelInfo> LevelList;
        private GameObject LevelTemplate;
    
        public void RefreshUI()
        {
            //刷新Grid
            XUIHelper.ResizeUIGridGameObjects(LevelGrid, LevelList.Count, LevelTemplate);
    
            var idx = 0;
            foreach (var levelInfo in LevelList)
            {
                var child = LevelGrid.transform.GetChild(idx);
                child.name = "Level-"+levelInfo.Id;
                GetControl<UILabel>("Label", child).text = levelInfo.Name;
                child.GetComponent<UIEventListener>().onClick = OnClickLevel;
    
                //...... 其它的操作
                idx++;
            }
            LevelGrid.GetComponent<UIGrid>().enabled = true;
            LevelGrid.Reposition();
        }
    
        void OnClickLevel(GameObject obj)
        {
            
        }
    }
  • 相关阅读:
    Velocity(7)——#foreach指令
    如何修改Struts2 FiledError样式
    Mysql:User does not have access to metadata required to determine stored procedure parameter types.
    Velocity(8)——引入指令和#Stop指令
    GUI设计禁忌 之一 ——使用了错误的控件
    GUI设计禁忌——基本原则
    Velocity(9)——宏
    CentOS NFS配置
    Velocity(10)——指令的转义
    从HTML到SSI框架
  • 原文地址:https://www.cnblogs.com/zhaoqingqing/p/4919980.html
Copyright © 2011-2022 走看看