性能优化
排行榜,邮件,关卡等数据列表项,一般在玩家打开面板时,都会重新刷新一次数据,那是否有必要每次都生成列表项呢?
假如每次列表的内容有变动就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)
{ }
}