今天说一下读取Json文件,生成菜单树。
菜单树可以直接去Asset Store搜索TreeView
,下载免费的那个
那么拿到菜单树之后,怎么将Json数据植入到我菜单树里面呢?
这就需要我们对Json文件做一些处理了。
既然称之为树,那么深度肯定是必不可少的东西,以根节点深度0为基准,子节点深度为1,孙节点深度为2等。知道了每个节点的深度,还得知道父节点是谁,否则就是某个孙子知道自己有爷爷,但是不知道自己爷爷是谁了。
有了父子关系和深度,那么就好办了
首先根据Json数据计算出最大深度,这决定了我们要创建多少级菜单。
直接上代码:
public struct MenuTree
{
public string name;
public string type;
public float id;
public float depth;
public float parentId;
public Color color;
public string info;
public string state;
public string equipment;
public string component;
public FaultItem[] faultItem;
}
public static MenuTree[] LoadMenuTreeData(JsonData jd)
{
menuTreeDatas = new MenuTree[jd.Count];
for (int i = 0; i < jd.Count; i++)
{
faultItems = new FaultItem[jd[i]["faultItem"].Count];
for (int j = 0; j < jd[i]["faultItem"].Count; j++)
{
faultItems[j].faultName = jd[i]["faultItem"][j]["faultName"].ToString();
faultItems[j].faultId =int.Parse(jd[i]["faultItem"][j]["faultId"].ToString());
}
menuTreeDatas[i].name = jd[i]["name"].ToString().TrimEnd();
menuTreeDatas[i].type = jd[i]["type"].ToString().TrimEnd();
menuTreeDatas[i].id = float.Parse(jd[i]["id"].ToString());
menuTreeDatas[i].depth = float.Parse(jd[i]["depth"].ToString());
menuTreeDatas[i].parentId = float.Parse(jd[i]["parentId"].ToString());
menuTreeDatas[i].info = jd[i]["info"].ToString();
menuTreeDatas[i].state = jd[i]["state"].ToString();
menuTreeDatas[i].equipment = jd[i]["equipment"].ToString();
menuTreeDatas[i].faultItem = faultItems;
}
return menuTreeDatas;
}
public static MenuTree[] LoadLocalMenuTree()
{
string ta = File.ReadAllText(Application.streamingAssetsPath + "/MenuTree.json");
JsonData jd = JsonMapper.ToObject(ta.ToString());
menuTreeDatas = LoadMenuTreeData(jd);
return menuTreeDatas;
}
public static float GetMaxDepth()
{
MenuTree[] tmp = DataHandler.LoadLocalMenuTree();
float maxDepth = tmp[0].depth;
for (int i = 1; i < CV_DataHandler.LoadLocalMenuTree().Length; i++)
{
if (maxDepth < tmp[i].depth)
maxDepth = tmp[i].depth;
}
return maxDepth;
}
好的,获取到了最大深度,那么我们就可以大刀阔斧地干了,直接找到导入的Example脚本,挂载在空物体上,然后再添加TreeViewControl脚本,把所有你能看到的ParentControl变量都拖上去,然后修改Example脚本的PopulateExampleData
方法:
public static void PopulateExampleData(TreeViewControl item)
{
MenuTree[] tmp = DataHandler.LoadLocalMenuTree();
item.Width = 260;
item.Height = 1000;
item.Header = "-1节点";//根节点的父节点,也可以直接作为根节点
List<MenuTree> menuTree = tmp.ToList();
float dep = DataHandler.GetMaxDepth();
for (int i = 0; i <= dep; i++)
{
foreach (var it in menuTree)
{
if (it.depth.Equals(i))
{
TreeViewItem tvitem = new TreeViewItem(null, null);//生成新的菜单项
float pd = it.parentId;//父物体ID
string _name = it.name;
if (pd < 0)//根节点没有父物体,父物体ID小于0就行
tvitem = item.RootItem.AddItem(_name);
else
tvitem = treeViewItemList.Find(x => x.ID.Equals(pd)).AddItem(_name);
tvitem.ID = it.id;
tvitem.equipmentName = it.equipment;
tvitem.myName = it.name;
AddEvents(tvitem);
treeViewItemList.Add(tvitem);
addName.Add(_name);
}
}
}
}
于是我们就能得到我们想要的效果了,其中TreeViewItem可以添加自己想要存储的变量,点击的时候可以获取这些变量。
当我们敲代码的时候遇到某些逻辑问题难以捋清的时候,不妨试一试通过伪代码,或者直接一行一行先用文字述清每一步的逻辑,再回过头来,事情也许就能变的简单很多。
周更,迟交一天,罪过