Unity用UGUI实现简单的TreeView

创建TreeItem使用的Prefab

Unity用UGUI实现简单的TreeView_第1张图片
Unity用UGUI实现简单的TreeView_第2张图片

Unity用UGUI实现简单的TreeView_第3张图片

Unity用UGUI实现简单的TreeView_第4张图片

场景中创建一个TreeView

Unity用UGUI实现简单的TreeView_第5张图片
Unity用UGUI实现简单的TreeView_第6张图片

全部代码

public class TreeView : MonoBehaviour
{
    [SerializeField] private GameObject ItemPrefab;
    public Action<TreeItem> OnItemClick;
    public void LoadTree(IEnumerable<TreeItem> treeTtems)
    {
        LoadTree(treeTtems, transform);
    }
    private void LoadTree(IEnumerable<TreeItem> treeTtems, Transform _itemParentTran, TreeItem _itemParent = null)
    {
        foreach (TreeItem treeItem in treeTtems)
        {
            var itemTran = Instantiate(ItemPrefab, _itemParentTran).GetComponent<RectTransform>();
            var itemButton = itemTran.Find("Content").GetComponent<Button>();
            var headText = itemButton.transform.Find("Text").GetComponent<Text>();
            headText.text = treeItem.Name;
            if (treeItem.Height == 0) treeItem.Height = ItemPrefab.GetComponent<RectTransform>().sizeDelta.y;
            treeItem.transform = itemTran;
            treeItem.parent = _itemParent;
            itemButton.onClick.AddListener(() =>
            {
                treeItem.IsOpen = !treeItem.IsOpen;

                itemTran.DOSizeDelta(new Vector2(itemTran.sizeDelta.x, treeItem.GetRealHeight()), 0.2f);

                treeItem.parent.ResetHeight();

                OnItemClick?.Invoke(treeItem);
            });
            var childParent = itemTran.Find("Children");
            if (treeItem.Children != null && treeItem.Children.Count() > 0)
            {
                LoadTree(treeItem.Children, childParent, treeItem);
            }
            if (treeItem.IsOpen) itemTran.sizeDelta = new Vector2(itemTran.sizeDelta.x, treeItem.GetRealHeight());

            LayoutRebuilder.ForceRebuildLayoutImmediate(itemTran);
        }
    }
}
/// 
/// TreeView的Item
/// 
public class TreeItem
{
    /// 
    /// TreeItem的
    /// 
    public Transform transform { get; set; }
    /// 
    /// TreeItem的父级
    /// 
    public TreeItem parent { get; set; }
    public int Id { get; set; }
    public string Name { get; set; }
    /// 
    /// 子级集合
    /// 
    public IEnumerable<TreeItem> Children { get; set; }
    /// 
    /// 是否展开/打开
    /// 
    public bool IsOpen { get; set; }
    /// 
    /// 高度,如果没有指定则获取Prefab的高度
    /// 
    public float Height { get; set; }
}
public static class TreeItemBaseExtension
{
    /// 
    /// 获取真实高度(包含子列表的高度)
    /// 
    /// 
    /// 
    public static float GetRealHeight(this TreeItem item)
    {
        float tempHeight = 0f;
        getChildrenHeight(item, ref tempHeight);
        return tempHeight;
    }
    private static void getChildrenHeight(TreeItem treeItem, ref float height)
    {
        height += treeItem.Height;
        if (treeItem.IsOpen && treeItem.Children != null)
        {
            foreach (var item in treeItem.Children)
            {
                getChildrenHeight(item, ref height);
            }
        }
    }
    /// 
    /// 刷新父级高度
    /// 
    /// 
    public static void ResetHeight(this TreeItem treeItem)
    {
        if (treeItem != null)
        {
            var rect = treeItem.transform.GetComponent<RectTransform>();

            rect.DOSizeDelta(new Vector2(rect.sizeDelta.x, treeItem.GetRealHeight()), 0.2f);

            treeItem.parent.ResetHeight();
        }
    }
    /// 
    /// 是否存在子列表
    /// 
    /// 
    /// 
    public static bool HasChild(this TreeItem treeItem)
    {
        return treeItem.Children != null;
    }
}

调用

        treeView.LoadTree(list);
        treeView.OnItemClick += item =>
        {
            if (!item.HasChild())
                Debug.Log(item.Name);
        };

你可能感兴趣的:(Unity,C#,unity,c#,游戏引擎)