看美女先!!!
步入正题!!
首先,实现搜索功能,肯定需要一个搜索的列表,需要一个inputfield检测用户输入,同时在列表当中匹配用户输入的字段,并显示出来。那基于这个逻辑,不难先到会用到两个组件:InputField以及 Scroll View。
为什么不用dropdown呢?其实在了解到这个需求的时候就有查过资料,但是这个资料好像挺少的,也有可能我搜索的不对,没有找到什么有用的方法去实现,就基于我自己的理解,写的。后来有看到dropdown这个组件,也尝试了一下,但我好像没找到一个好的处理方式。就没有用了。下面就讲讲我怎么写的吧。
首先是界面的搭建了,大概就是需要一个Scroll View显示当前所有的列表,需要一个InputField来获取用户输入,再是需要一个Scroll View显示搜索出来的列表。那么界面搭建就是如下:
生成列表时用到的预制体:
代码部分,因为只是测试,还是比较简单的。我是菜鸟,有不对的地方,还请多多包涵,多多指教!!
这里用了两个脚本,其实可以合到一起:Manager.cs 和Search.cs。大概逻辑就是,用户有输入时把搜索列表显示,初始列表隐藏,没有输入时把搜索列表隐藏,初始列表显示。
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Manager : MonoBehaviour
{
[Tooltip("检测用户输入的输入框")]
[SerializeField] InputField input;
[Tooltip("所有列表的存放位置")]
[SerializeField] Transform content;
[SerializeField] GameObject scrollRect;
[Tooltip("数据集合的可视化(方便查看数据)")]
[SerializeField] List<DeviceDataSet> dataList;
[Tooltip("搜索出来的列表存放位置")]
[SerializeField] Transform ShowContent;
[SerializeField] GameObject contentScrollRect;
[Tooltip("要生成的预制体")]
[SerializeField] GameObject itemPrefab;
private void Start()
{
dataList = new List<DeviceDataSet>();
InitDataList();
}
/// <summary>
/// 初始化
/// </summary>
private void InitDataList()
{
for (int i = 0; i < 300; i++)
{
var dataSet = new DeviceDataSet();
dataSet.name = i.ToString();
var ran = UnityEngine.Random.Range(0, 5);
string name = null;
switch (ran)
{
case 0:
name = "玫瑰的哭呼呼玫瑰的哭呼呼玫瑰的哭呼呼玫瑰的哭呼呼玫瑰的哭呼呼玫瑰的哭";
break;
case 1:
name = "家大叔牛逼清德的回家大叔牛逼清德的回家大叔牛逼";
break;
case 2:
name = "走走走走走走走走走走走走走走走走走走走走走走走走走走走走走走走走刷口的小孩";
break;
case 3:
name = "沙河";
break;
case 4:
name = "偷小孩了偷小孩了偷小孩了";
break;
}
dataSet.id = i + name;
dataList.Add(dataSet);
var go= Search.FindChild(content, itemPrefab);
go.transform.Find("name").GetComponent<Text>().text = dataSet.name;
go.transform.Find("id").GetComponent<Text>().text = dataSet.id;
}
contentScrollRect.SetActive(true);
input.onValueChanged.AddListener(OnSearch);
}
/// <summary>
/// 搜索
/// </summary>
/// <param name="arg0"></param>
private void OnSearch(string arg0)
{
foreach (Transform item in ShowContent)
{
item.gameObject.SetActive(false);
}
if (!string.IsNullOrEmpty(arg0))
{
contentScrollRect.SetActive(false);
scrollRect.gameObject.SetActive(true);
Search.SearchDevice(ShowContent, arg0, dataList, itemPrefab,ChildSelect);
}
else
{
scrollRect.gameObject.SetActive(false);
contentScrollRect.SetActive(true);
}
}
/// <summary>
/// 预制体按钮点击事件
/// </summary>
/// <param name="go"></param>
public void ChildSelect(Transform go)
{
input.text = go.Find("id").GetComponent<Text>().text;
scrollRect.SetActive(false);
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public static class Search
{
/// <summary>
/// 搜索满足条件的列表
/// </summary>
/// <param name="content"></param>
/// <param name="str"></param>
/// <param name="devices"></param>
/// <param name="itemPrefab"></param>
/// <param name="action"></param>
public static void SearchDevice(Transform content, string str, List<DeviceDataSet> devices, GameObject itemPrefab, Action<Transform> action)
{
for (int i = 0; i < devices.Count; i++)
{
if (devices[i].id.IndexOf(str) != -1)
{
var go = FindChild(content, itemPrefab, action);
go.transform.Find("id").GetComponent<Text>().text = devices[i].id;
go.transform.Find("name").GetComponent<Text>().text = devices[i].name;
}
}
}
/// <summary>
/// 生成预制体,这里用了对象池的概念
/// </summary>
/// <param name="ShowContent"></param>
/// <param name="itemPrefab"></param>
/// <param name="action"></param>
/// <returns></returns>
public static GameObject FindChild(Transform ShowContent, GameObject itemPrefab, Action<Transform> action = null)
{
foreach (Transform item in ShowContent)
{
if (!item.gameObject.activeSelf)
{
item.GetChild(0).GetComponent<Text>().text = null;
item.GetChild(1).GetComponent<Text>().text = null;
item.gameObject.SetActive(true);
return item.gameObject;
}
}
var child = GameObject.Instantiate(itemPrefab, ShowContent);
child.GetComponent<Button>().onClick.AddListener(() => { action?.Invoke(child.transform); });
return child;
}
}
[Serializable]
public class DeviceDataSet
{
public string name;
public string id;
}