[UnityUI]动态滑动列表

UI布局是这样滴:


[UnityUI]动态滑动列表_第1张图片

具体的关于滑动列表的设置可以参考这里,其中Image的Scroll Rect组件的Content赋值为Content,在这里,我们的Content是一个空物体,它的大小就是上图那个方框的大小。这里有两点很重要:

1.Content的Pivot的Y必须设置为Y的最大值,就像这样:


这是为什么呢?其实动态滑动列表的原理主要就是动态改变Content的Height,当中心点处于最顶的位置时,就能保证顶部位置不变,只有下部的位置在变化。假如中心点处于中间位置,那么改变Height,两边都会变化。

2.列表项的设置,要注意列表项预制体的Anchor Presets和Pivot,因为它们都会影响预制体实例化的位置,这里为了方便计算,我设置Anchor Presets为top-center,Pivot为(0.5,1)


最后给出代码:

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class TaskPanel : MonoBehaviour {

    public static TaskPanel instance;
    public List<GameObject> items = new List<GameObject>();

    public GameObject content;//内容
    public Vector2 contentSize;//内容的原始高度

    public GameObject item;//列表项
    public float itemHeight;
    public Vector3 itemLocalPos;
    
    void Awake()
    {
        if (!instance)
            instance = this;
        else
            Destroy(this);
    }

    void Start()
    {
        content = GameObject.Find("Content");
        contentSize = content.GetComponent<RectTransform>().sizeDelta;

        item = Resources.Load("Item") as GameObject;
        itemHeight = item.GetComponent<RectTransform>().rect.height;
        itemLocalPos = item.transform.localPosition; 
    }

    //添加列表项
    public void AddItem()
    {
        GameObject a = Instantiate(item) as GameObject;
        a.transform.parent = content.transform;
        a.transform.localPosition = new Vector3(itemLocalPos.x, itemLocalPos.y - items.Count * itemHeight, 0);
        items.Add(a);

        if (contentSize.y <= items.Count * itemHeight)//增加内容的高度
        {
            content.GetComponent<RectTransform>().sizeDelta = new Vector2(contentSize.x, items.Count * itemHeight);
        }
    }

    //移除列表项
    public void RemoveItem(GameObject t)
    {
        int index = items.IndexOf(t);
        items.Remove(t);
        Destroy(t);

        for (int i = index; i < items.Count; i++)//移除的列表项后的每一项都向前移动
        {
            items[i].transform.localPosition += new Vector3(0, itemHeight, 0);
        }

        if (contentSize.y <= items.Count * itemHeight)//调整内容的高度     
            content.GetComponent<RectTransform>().sizeDelta = new Vector2(contentSize.x, items.Count * itemHeight);
        else
            content.GetComponent<RectTransform>().sizeDelta = contentSize;
    }
}

效果图:

[UnityUI]动态滑动列表_第2张图片


///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

后面改进了一下:


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

public class ScrollPanelVerticalLayout : MonoBehaviour {

    private List<Transform> items = new List<Transform>();
    private RectTransform contentRectTra;//内容  
    private VerticalLayoutGroup group;//用于计算内容的高度
    private float itemHeight;//子项的高度

	void Awake () 
    {
        contentRectTra = transform.FindChild("Content").GetComponent<RectTransform>();
        contentRectTra.sizeDelta = new Vector2(contentRectTra.sizeDelta.x, 0);
        group = contentRectTra.GetComponent<VerticalLayoutGroup>();
	}

    //添加列表项  
    public void AddItem(Transform t)
    {
        if (itemHeight == 0f) itemHeight = t.GetComponent<RectTransform>().rect.height;

        t.SetParent(contentRectTra.transform);
        t.localScale = Vector3.one;
        items.Add(t);

        contentRectTra.sizeDelta = new Vector2(contentRectTra.sizeDelta.x, 
            group.padding.top + group.padding.bottom + items.Count * itemHeight + (items.Count - 1) * group.spacing);
    }

    //移除列表项  
    public void RemoveItem(Transform t)
    {
        //Debug.Log(t.gameObject.name);
        int index = items.IndexOf(t);
        items.Remove(t);
        Destroy(t.gameObject);

        contentRectTra.sizeDelta = new Vector2(contentRectTra.sizeDelta.x,
            group.padding.top + group.padding.bottom + items.Count * itemHeight + (items.Count - 1) * group.spacing);
    }  

}

使用起来也很方便:

using UnityEngine;
using System.Collections;
using UnityEngine.UI;

public class Test : MonoBehaviour {

    public ScrollPanelVerticalLayout scrollPanel;

    private int index = 0;
    public void Add()
    {
        GameObject go = Instantiate(Resources.Load("Item")) as GameObject;
        go.name = index.ToString();
        go.transform.FindChild("Text").GetComponent<Text>().text = index.ToString();
        go.transform.FindChild("Button").GetComponent<Button>().onClick.AddListener
        (
            () =>
            {
                Remove(go.transform);
            }
        );

        scrollPanel.AddItem(go.transform);
        index++;
    }

    void Remove(Transform t)
    {
        scrollPanel.RemoveItem(t);
    }

}


你可能感兴趣的:(UGUI,动态滑动列表)