Unity 仿QQ列表的折叠菜单

主要用到了GUI的自动布局功能,VerticalLayoutGroup,注意ChildControlsSize 和ChildForceExpand属性设置为 Width

Unity 仿QQ列表的折叠菜单_第1张图片
效果:
Unity 仿QQ列表的折叠菜单_第2张图片
实现代码:

/// 
/// 折叠菜单
/// 
public class FoldPanel : MonoBehaviour
{
    [SerializeField]
    private GameObject panelItem; // 折叠页
    [SerializeField]
    private TitleItem titleItem;
    [SerializeField]
    private DataItem dataItem;

    public List<FoldData> dataList = new List<FoldData>();

    private void Start()
    {
        Create();
    }

    public void Create()
    {
        for (int i = 0; i < dataList.Count; i++)
        {
            // 创建标题
            TitleItem title = Instantiate(titleItem).GetComponent<TitleItem>();
            title.SetTitle(dataList[i].titleName);
            title.transform.SetParent(this.transform);

            // 创建子折叠面板
            GameObject panel = Instantiate(panelItem);
            panel.transform.SetParent(this.transform);
            // 260是折叠页的宽度,30DataItem的高度
            panel.GetComponent<RectTransform>().sizeDelta = new Vector3(260,30 * dataList[i].data.Count);
            title.SetFoldPanel(panel);
            panel.SetActive(false);

            // 创建折叠页数据
            for (int j = 0; j < dataList[i].data.Count; j++)
            {
                DataItem item = Instantiate(dataItem).GetComponent<DataItem>();
                item.transform.SetParent(panel.transform);
                item.SetInfo(dataList[i].data[j]);
            }
        }
    }
}

[System.Serializable]
public class FoldData
{
    public string titleName;
    public List<ItemData> data;
}

[System.Serializable]
public class ItemData
{
    public string userName;
    //public string imageName;
    public Sprite imageName;
}

TitleItem.cs

public class TitleItem : MonoBehaviour,IPointerClickHandler
{
    [SerializeField]
    private Text title;
    [SerializeField]
    private Transform arrow;

    public bool isFold = true;  // 是否是折叠状态
    public Transform foldPanel; 

    public void OnPointerClick(PointerEventData eventData)
    {
        if (isFold)
        {
            isFold = false;

            arrow.DORotate(Vector3.zero, 0.1f);

            if (foldPanel != null)
            {
                foldPanel.gameObject.SetActive(true);
                foldPanel.DOScaleY(1, 0.1f);
            }
        }
        else
        {
            isFold = true;
            arrow.DORotate(new Vector3(0, 0, 90), 0.1f);
            
            if (foldPanel != null)
            {
                foldPanel.DOScaleY(0, 0.1f).OnComplete(() => { foldPanel.gameObject.SetActive(false); });
            }
        }
    }

    public void SetTitle(string _titleName)
    {
        title.text = _titleName;
    }

    public void SetFoldPanel(GameObject panel)
    {
        foldPanel = panel.transform;
    }
}

列表的数据来源是在界面上手动配置的,当然如果想要读取本地或者服务器的数据也是可以的。

你可能感兴趣的:(Unity)