Unity 首字母检索器

需要实现一个类似 “城市选择器”的功能 网上基本都是用原生或者前端来实现功能 其他大概的思路都差不多 这里提供一个Unity 实现的思路 

先看一下效果

这里用到了 SuperScrollView 这个插件 来实现功能

ListText.cs  // 核心控制类  代码写的比较随意 大概的功能已经实现,需要根据实际需要进行优化。

using SuperScrollView;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class ListText : MonoBehaviour
{
    public LoopListView2 mLoopListView;
    public Text Select_Text;
    public RectTransform Right_Content;
    public GameObject Tag_Prefab;
    public string[] Tags = new string[] { "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "#" };

    public int TreeViewItemCount
    {
        get
        {
            return mItemDataList.Count;
        }
    }
    // Start is called before the first frame update
    void Start()
    {
        Init();

        Keys.Clear();
        for (int i = 0; i < Tags.Length; ++i)
        {
            CityData cityData = new CityData();
            cityData.Key = Tags[i];
            List<string> value = new List<string>();
            value.Add("Item" + Tags[i] + Random.Range(0, 6).ToString());
            cityData.Value = value;

            Keys.Add(cityData);
        }
        DoRefreshDataSource();
        int count = TreeViewItemCount;
        //tells mTreeItemCountMgr there are how many TreeItems and every TreeItem has how many ChildItems.
        for (int i = 0; i < count; ++i)
        {
            int childCount = GetItemDataByIndex(i).ChildCount;
            //second param "true" tells mTreeItemCountMgr this TreeItem is in expand status, that is to say all its children are showing.
            AddTreeItem(childCount, true);
        }

        mLoopListView.InitListView(GetTotalItemAndChildCount(), OnGetItemByIndex);
    }

    public void AddTreeItem(int count, bool isExpand)
    {
        KeyData data = new KeyData();
        data.mTreeItemIndex = mTreeItemDataList.Count;
        data.mChildCount = count;
        data.mIsExpand = isExpand;
        mTreeItemDataList.Add(data);
        mIsDirty = true;
    }
    public int GetTotalItemAndChildCount()
    {
        int count = mTreeItemDataList.Count;
        if (count == 0)
        {
            return 0;
        }
        UpdateAllTreeItemDataIndex();
        return mTreeItemDataList[count - 1].mEndIndex + 1;
    }
    LoopListViewItem2 OnGetItemByIndex(LoopListView2 listView, int index)
    {
        if (index < 0)
        {
            return null;
        }

        KeyData countData = QueryTreeItemByTotalIndex(index);
        if (countData == null)
        {
            return null;
        }
        int treeItemIndex = countData.mTreeItemIndex;
        ValueData treeViewItemData = GetItemDataByIndex(treeItemIndex);
        if (countData.IsChild(index) == false)// if is a TreeItem
        {
            //get a new TreeItem
            LoopListViewItem2 item = listView.NewListViewItem("KeyItem");
            KeyItem itemScript = item.GetComponent<KeyItem>();
            if (item.IsInitHandlerCalled == false)
            {
                item.IsInitHandlerCalled = true;
                itemScript.Init();
                //itemScript.SetClickCallBack(this.OnExpandClicked);
            }
            //update the TreeItem's content
            itemScript.mText.text = treeViewItemData.mName;
            itemScript.SetItemData(treeItemIndex, countData.mIsExpand);
            return item;
        }
        else // if is a TreeChildItem
        {
            //childIndex is from 0 to ChildCount.
            //for example, TreeChildItem0_0 is the 0'th child of TreeItem0
            //and TreeChildItem1_2 is the 2'th child of TreeItem1
            int childIndex = countData.GetChildIndex(index);
            ItemData itemData = treeViewItemData.GetChild(childIndex);
            if (itemData == null)
            {
                return null;
            }
            //get a new TreeChildItem
            LoopListViewItem2 item = listView.NewListViewItem("ValueItem");
            ValueItem itemScript = item.GetComponent<ValueItem>();
            if (item.IsInitHandlerCalled == false)
            {
                item.IsInitHandlerCalled = true;
                itemScript.Init();
            }
            //update the TreeChildItem's content
            itemScript.SetItemData(itemData, treeItemIndex, childIndex);
            return item;
        }

    }

    List<ValueData> mItemDataList = new List<ValueData>();

    int mTreeViewItemCount = 20;
    int mTreeViewChildItemCount = 30;

    // List<string, List<string>> keys = new List<string, List<string>>();


    ArrayList Keys = new ArrayList();

    void DoRefreshDataSource()
    {
        mItemDataList.Clear();


        for (int i = 0; i < Keys.Count; i++)
        {
            ValueData tData = new ValueData();
            CityData city = Keys[i] as CityData;
            tData.mName = "" + city.Key;
            mItemDataList.Add(tData);
            // int childCount = Random.Range(0, 6);
            for (int j = 0; j < city.Value.Count; j++)
            {
                ItemData childItemData = new ItemData();
                childItemData.mName = "Item" + city.Value[j] + ":Child" + j;
                childItemData.mDesc = "Item Desc For " + childItemData.mName;
                childItemData.mStarCount = Random.Range(0, 6);
                childItemData.mFileSize = Random.Range(20, 999);
                tData.AddChild(childItemData);
            }
        }
        //for (int i = 0; i < keys.Count; ++i)
        //{
        //    ValueData tData = new ValueData();
        //    tData.mName = "" + keys[]
        //    mItemDataList.Add(tData);
        //    int childCount = Random.Range(0, 6);

        //}
    }

    public void AddItem()
    {
        // string key = Tags[Random.Range(0, Tags.Length)];
        //   int itemIndex = Random.Range(0, Tags.Length);
        int itemIndex = 0;
        CityData cityData = Keys[itemIndex] as CityData;

        cityData.Value.Add(cityData.Key + "测试");

        Keys[itemIndex] = cityData;
      
        //  int itemIndex = 0;
        int childIndex = 0;

        if (childIndex < 0)
        {
            childIndex = 0;
        }
        KeyData itemCountData = GetTreeItem(itemIndex);
        if (itemCountData == null)
        {
            return;
        }
        AddNewItemChildForTest(itemIndex, childIndex);
        int childCount = itemCountData.mChildCount;
        SetItemChildCount(itemIndex, childCount + 1);
        DoRefreshDataSource();
        mLoopListView.SetListItemCount(GetTotalItemAndChildCount(), false);

        mLoopListView.RefreshAllShownItem();
    }
    public void SetItemChildCount(int treeIndex, int count)
    {
        if (treeIndex < 0 || treeIndex >= mTreeItemDataList.Count)
        {
            return;
        }
        mIsDirty = true;
        KeyData data = mTreeItemDataList[treeIndex];
        data.mChildCount = count;
    }
    public void AddNewItemChildForTest(int itemIndex, int AddToBeforeChildIndex)
    {
        if (itemIndex < 0 || itemIndex >= mItemDataList.Count)
        {
            return;
        }
        ValueData tData = mItemDataList[itemIndex];
        List<ItemData> childItemDataList = tData.mChildItemDataList;
        ItemData childItemData = new ItemData();
        childItemData.mName = "Item" + itemIndex + ":" + AddToBeforeChildIndex;
        childItemData.mDesc = "Item Desc For " + childItemData.mName;
        childItemData.mStarCount = Random.Range(0, 6);
        childItemData.mFileSize = Random.Range(20, 999);
        if (AddToBeforeChildIndex < 0)
        {
            childItemDataList.Insert(0, childItemData);
        }
        else if (AddToBeforeChildIndex >= childItemDataList.Count)
        {
            childItemDataList.Add(childItemData);
        }
        else
        {
            childItemDataList.Insert(AddToBeforeChildIndex, childItemData);
        }

    }

    public ValueData GetItemDataByIndex(int index)
    {
        if (index < 0 || index >= mItemDataList.Count)
        {
            return null;
        }
        return mItemDataList[index];
    }

    List<KeyData> mTreeItemDataList = new List<KeyData>();
    KeyData mLastQueryResult = null;
    bool mIsDirty = true;
    public KeyData QueryTreeItemByTotalIndex(int totalIndex)
    {
        if (totalIndex < 0)
        {
            return null;
        }
        int count = mTreeItemDataList.Count;
        if (count == 0)
        {
            return null;
        }
        UpdateAllTreeItemDataIndex();
        if (mLastQueryResult != null)
        {
            if (mLastQueryResult.mBeginIndex <= totalIndex && mLastQueryResult.mEndIndex >= totalIndex)
            {
                return mLastQueryResult;
            }
        }
        int low = 0;
        int high = count - 1;
        KeyData data = null;
        while (low <= high)
        {
            int mid = (low + high) / 2;
            data = mTreeItemDataList[mid];
            if (data.mBeginIndex <= totalIndex && data.mEndIndex >= totalIndex)
            {
                mLastQueryResult = data;
                return data;
            }
            else if (totalIndex > data.mEndIndex)
            {
                low = mid + 1;
            }
            else
            {
                high = mid - 1;
            }
        }
        return null;
    }
    void UpdateAllTreeItemDataIndex()
    {
        if (mIsDirty == false)
        {
            return;
        }
        mLastQueryResult = null;
        mIsDirty = false;
        int count = mTreeItemDataList.Count;
        if (count == 0)
        {
            return;
        }
        KeyData data0 = mTreeItemDataList[0];
        data0.mBeginIndex = 0;
        data0.mEndIndex = (data0.mIsExpand ? data0.mChildCount : 0);
        int curEnd = data0.mEndIndex;
        for (int i = 1; i < count; ++i)
        {
            KeyData data = mTreeItemDataList[i];
            data.mBeginIndex = curEnd + 1;
            data.mEndIndex = data.mBeginIndex + (data.mIsExpand ? data.mChildCount : 0);
            curEnd = data.mEndIndex;
        }
    }
    public KeyData GetTreeItem(int treeIndex)
    {
        if (treeIndex < 0 || treeIndex >= mTreeItemDataList.Count)
        {
            return null;
        }
        return mTreeItemDataList[treeIndex];
    }
    public void OnJumpBtnClicked(int itemIndex)
    {
        // int itemIndex = 0;
        int childIndex = 0;
        int finalIndex = 0;
        if (childIndex < 0)
        {
            childIndex = 0;
        }
        KeyData itemCountData = GetTreeItem(itemIndex);
        if (itemCountData == null)
        {
            return;
        }
        int childCount = itemCountData.mChildCount;
        if (itemCountData.mIsExpand == false || childCount == 0 || childIndex == 0)
        {
            finalIndex = itemCountData.mBeginIndex;
        }
        else
        {
            if (childIndex > childCount)
            {
                childIndex = childCount;
            }
            if (childIndex < 1)
            {
                childIndex = 1;
            }
            finalIndex = itemCountData.mBeginIndex + childIndex;
        }
        mLoopListView.MovePanelToItemIndex(finalIndex, 0);
    }


    public void Init()
    {
        int Index = 0;
        foreach (string Value in Tags)
        {
            GameObject go = Instantiate(Tag_Prefab, Right_Content);
            go.name = "Tag-" + Value;
            Tag_Item tag_Item = go.GetComponent<Tag_Item>();
            tag_Item.Select_Text = Select_Text;
            tag_Item.Init(Value);
            tag_Item.Index = Index;
            tag_Item.KeyStr = Value;
            tag_Item.listText = this;
            Index += 1;
        }
    }


}

public class CityData
{
    public string Key;
    public List<string> Value;
}

这里提供 源码下载  unity版本2019.4.6 低版本也可以打开   https://download.csdn.net/download/a1228267639/13195713 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值