Unity搜索组件工具

1.核心搭建就是一个InputField 一个Scroll view 

代码如下:

using System;
using System.Collections.Generic;

using UnityEngine;
using UnityEngine.UI;

/// <summary>
/// Unity 搜索组件:输入框模糊搜索字典Key,Scroll View展示结果,点击结果触发回调
/// </summary>
public class SearchScrollView : MonoBehaviour
{
    [Header("UI References")]
    [SerializeField] private InputField searchInput;
    [SerializeField] private RectTransform contentRoot;
    [SerializeField] private GameObject resultItemPrefab;

    [Header("Settings")]
    public static bool isbool = false;
    /// <summary> 数据源:Key=显示文本,Value=关联数据 </summary>
    private Dictionary<string, string> dataSource = new Dictionary<string, string>();

    /// <summary> 点击结果项的回调,参数为 key 和对应的 value </summary>
    public event Action<string, string> OnResultClicked;

    /// <summary> 对象池:缓存已创建的 Item,避免频繁 Instantiate/Destroy </summary>
    private List<GameObject> pool = new List<GameObject>();
    private int poolIndex = 0;

    private void Awake()
    {
        if (searchInput != null)
            searchInput.onValueChanged.AddListener(OnSearchTextChanged);
       
    }

    private void OnDestroy()
    {
        if (searchInput != null)
            searchInput.onValueChanged.RemoveListener(OnSearchTextChanged);
        // 清理对象池
        foreach (var obj in pool)
        {
            if (obj != null) Destroy(obj);
        }
        pool.Clear();
    }

    /// <summary> 设置数据源并刷新展示 </summary>
    public void SetDataSource(Dictionary<string, string> data)
    {
        dataSource = data ?? new Dictionary<string, string>();
        RefreshResults(searchInput != null ? searchInput.text : "");
    }

    /// <summary> 模糊匹配:keyword 包含在 key 中即匹配(忽略大小写) </summary>
    private bool FuzzyMatch(string key, string keyword)
    {
        if (string.IsNullOrEmpty(keyword)) return true;
        return key.IndexOf(keyword, StringComparison.OrdinalIgnoreCase) >= 0;
    }

    #region 搜索与刷新

    private void OnSearchTextChanged(string searchText)
    {
        if (!string.IsNullOrWhiteSpace (searchText))
        {
            RefreshResults(searchText);
        }
        else
        {
            for (int i = 0; i < pool.Count; i++)
                pool[i].SetActive(false);
        }
       
    }

    private void RefreshResults(string searchText)
    {
        // 回收所有对象到池中(隐藏而非销毁)
        for (int i = 0; i < pool.Count; i++)
            pool[i].SetActive(false);
        poolIndex = 0;

        foreach (var kvp in GetExcelData.Instance.excelDatas)
        {
            if (FuzzyMatch(kvp.Key, searchText))
            {
                GetOrCreateItem(kvp.Key);
            }
        }
    }

    /// <summary> 从池中取一个空闲对象,不够时新建 </summary>
    private void GetOrCreateItem(string key)
    {
        GameObject itemObj;

        if (poolIndex < pool.Count)
        {
            // 池中有空闲对象,直接复用
            itemObj = pool[poolIndex];
        }
        else
        {
            // 池不够,新建一个加入池中
            itemObj = Instantiate(resultItemPrefab, contentRoot, false);
        

            pool.Add(itemObj);
        }

        poolIndex++;

    

        // 更新显示
        itemObj.name = key;
        var label = itemObj.GetComponentInChildren<Text>();
        if (label != null)
            label.text = key;

        itemObj.SetActive(true);

        var button = itemObj.GetComponent<Button>();
        if (button == null)
            button = itemObj.AddComponent<Button>();

        // 点击回调只绑定一次,通过 ItemData 传递数据
        button.onClick.RemoveAllListeners();
        button.onClick.AddListener(() =>
        {
            isbool = true;
                  
           //写你自己的按钮方法既可

        });
    }

    
    #endregion
}

 

posted @ 2026-05-29 10:55  剑起苍穹  阅读(3)  评论(0)    收藏  举报
/*鼠标点击特效*/