性能優化
排行榜,郵件,關卡等數據列表項,一般在玩家打開面板時,都會重新刷新一次數據,那是否有必要每次都生成列表項呢?
假如每次列表的內容有變動就Instance 新的Gameobject,這是沒有必要的浪費。本文想做的就是避免頻繁生成新的Gameobject。
運行效果
思路及流程圖
循環利用UIGrid下已有child,改變child的數據(不同child渲染不同的數據)。需要生成時就生成,不需要生成則根據情況顯示隱藏
流程圖如下所示
實現方法
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) { } }