接上周菜单树,链接: 菜单树生成.
菜单树的优势体现在便于上下级转换,但是当树的节点较多,深度较大的时候,想要找到某个节点,光靠一级一级展开也是麻烦
于是查询功能也就很有必要了。
首先创建一个InputField ,添加一个Button 搜索按钮
,UI就搭成了,也可以再创建一个Text warning
,作为查找无效时的警告提示。
接下来就是代码了,这里只是提供给大家一个思路,代码不一定拿到就能用,因为业务需求、数据内容都不一定一样
输入搜索信息,点击搜索,如果搜索到匹配的信息,那么将搜索到的菜单项显示不同的效果,同时如果菜单树是收起状态,则展开菜单树至搜索到的节点。还要能根据搜索字段,区别是完全匹配还是模糊搜索,以展现出不同的搜索结果。
我们拆开来操作,首先做个一搜索结果的显示效果,TreeViewControl使用的是GUISkin,我们可以创建一个GUISkin,修改Inspector面板的Button->Normal->BackGround,或者直接修改TextColor,如图:
然后修改TreeView插件的脚本,TreeView自带Hover、Unselected、Selected皮肤,我们需要做的就是添加一个Searched皮肤,具体修改的地方如图:
在TreeViewControl脚本中定义:
public GUISkin m_skinSearched = null;
在TreeViewInspector脚本的ApplySkin方法中修改:
foreach (TreeViewControl item in items)
{
if (null == item)
{
continue;
}
if (null == item.m_skinHover)
{
Debug.LogError("TreeView is missing Hover Skin");
continue;
}
if (null == item.m_skinSelected)
{
Debug.LogError("TreeView is missing Selected Skin");
continue;
}
if (null == item.m_skinUnselected)
{
Debug.LogError("TreeView is missing Unselected Skin");
continue;
}
if(null == item.m_skinSearched)
{
Debug.LogError("TreeView is missing Searched Skin");
continue;
}
// create new skin instance
GUISkin skinHover = (GUISkin)Object.Instantiate(item.m_skinHover);
GUISkin skinSelected = (GUISkin)Object.Instantiate(item.m_skinSelected);
GUISkin skinUnselected = (GUISkin)Object.Instantiate(item.m_skinUnselected);
GUISkin skinSearched = (GUISkin)Object.Instantiate(item.m_skinSearched);
// name the skins
skinHover.name = "Hover";
skinSelected.name = "Selected";
skinUnselected.name = "Unselected";
skinSearched.name = "Searched";
item.m_skinHover = skinHover;
item.m_skinSelected = skinSelected;
item.m_skinUnselected = skinUnselected;
item.m_skinSearched = skinSearched;
}
在TreeViewItem脚本中定义bool变量:
public bool IsSearch = false;
DisplayItem方法中添加代码,实现搜索结果展现不同的显示效果(286行左右)
if (IsSearch)
{
GUI.skin = ParentControl.m_skinSearched;
}
实现模糊查询功能
void Start()
{
searchBtn = GameObject.Find("搜索按钮").GetComponent<Button>();
searchBtn.onClick.AddListener(delegate () { Search(searchField.text); });//搜索按钮点击事件监听
}
private TreeViewItem treeItem;
private List<TreeViewItem> tmplist;
private List<TreeViewItem> searchList;
/// <summary>
/// 搜索菜单树
/// </summary>
/// <param name="str"></param>
public void Search(string str)
{
if (string.IsNullOrEmpty(str))
return;
Debug.Log("文本输入:" + str);
tmplist = Example.treeViewItemList;//Example是TreeView插件的示例脚本,treeViewItemList是生成每一项菜单时添加的列表
if ((treeItem = tmplist.Find(x => x.myName.Equals(str))) != null)
{
Debug.Log("查找到的为:" + treeItem.myName);
treeItem.IsSearch = true;//更改搜索结果菜单项的显示效果
treeItem.ParentControl.RootItem.IsExpanded = true;//默认根节点展开
Invoke(nameof(EndSearch), 1f);//1秒钟后取消显示效果
for (int i = 0; i < tmplist.Count; i++)//将所有查找到的祖先节点展开
{
for (int j = 0; j < treeItem.ancestors.Count; j++)
{
if (tmplist[i].ID == treeItem.ancestors[j])
tmplist[i].IsExpanded = true;
}
}
}
else if ((searchList = tmplist.FindAll(x => x.myName.Contains(str)).ToList()).Count > 0)
{
for (int i = 0; i < searchList.Count; i++)
{
searchList[i].IsSearch = true;
searchList[i].ParentControl.RootItem.IsExpanded = true;
Debug.Log("查找到的为:" + searchList[i].myName);
for (int j = 0; j < tmplist.Count; j++)
{
for (int k = 0; k < searchList[i].ancestors.Count; k++)
{
if (tmplist[j].ID == searchList[i].ancestors[k])
tmplist[j].IsExpanded = true;
}
}
}
Invoke(nameof(EndSearchList), 1f);
}
else
{
StartCoroutine(ReDisplay(true, inputFieldWarning.gameObject));
inputFieldWarning.text = string.Format("未查询到有关\"{0}\"的节点!\n请重新输入", CalculatorStrLenth(str, 7));
Debug.Log(string.Format("未查询到有关\"{0}\"的节点,请重新输入", str));
searchField.text = "";
}
}
/// <summary>
/// 计算输入的字符串长度,超出长度的部分以省略号显示
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public string CalculatorStrLenth(string str, int len)
{
string tmp = str;
if (str.Length > len)
{
tmp = string.Format("{0}...", str.Substring(0, len));
return tmp;
}
return tmp;
}
public void EndSearch()//等待一秒钟后恢复之前的显示效果
{
treeItem.IsSearch = false;
}
public void EndSearchList()//等待一秒钟后恢复之前的显示效果
{
for (int i = 0; i < searchList.Count; i++)
{
searchList[i].IsSearch = false;
}
}
好了,基于TreeView的模糊查询功能到这边就完美达成了。若有纰漏会另行补充