unity UGUI動態滑動列表


 

步驟:

     1.在SceneMail創建一個Panel 改名為ScrollRect,ScrollRect添加Mask和Scroll Rect組件,Scroll Rect組件勾選Vertical 只需要垂直滾動

     2.在SceneMail創建一個Scrollbar控件

     3.ScrollRect上添加子控件Panel 改名為ScorllView,ScorllView大小覆蓋ScrollRect

     4.ScorllView添加子控件Panel 改名為Content,Content大小覆蓋ScorllView

     5.Content添加Vertical Layout Group和Content size Fitter組件,Vertical Layout Group組件設置好間隔和對其方式,會自動排列我們添加的控件,Content size Fitter用來調整顯示內容

     6.將ScorllView、Content和Scrollbar分別拖到ScrollRect里面 如圖所示

 7.Scollbar組件屬性Direction修改成 Bottom To Top(往下拉將ScorllRect底部隱藏部分拖出來)

     8.制作Prefab Item

 

代碼

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

public class SceneMail : MonoBehaviour
{
    public Button mItemPrefab;//要添加到列表的預設體按鈕組件
    public Transform mContentTransform;//容器Content的transform
    public Scrollbar mScrollbar;//滑動條

    List<Button> lists = new List<Button>();//存放按鈕組件
    
    float itemHeight;//單個按鈕組件的height

    RectTransform rect;//容器content的rect

    public VerticalLayoutGroup group;//用於計算內容的高度

    // Use this for initialization
    void Start()
    {
        rect = mContentTransform.GetComponent<RectTransform>();
        itemHeight = mItemPrefab.GetComponent<RectTransform>().rect.height;
        

        ShowItems();
        mScrollbar.value = 1.0f;

    }

    /// <summary>
    /// 顯示Item列表
    /// </summary>
    void ShowItems()
    {
        for (int i = 0; i < 20; i++)
        {
            AddItem();
        }
    }
    void Update()
    {
        //添加
        if (Input.GetKeyDown(KeyCode.Alpha0))
        {
            AddItem();
        }
        //使列表跳轉到頂部
        if (Input.GetKeyDown(KeyCode.Alpha1))
        {
            ToTopFunc();
        }
        //清空列表
        if (Input.GetKeyDown(KeyCode.Alpha2))
        {
            ClearFunc();
        }
    }
    //添加組件
    void AddItem()
    {
        
        Button item = Instantiate(mItemPrefab, transform.position, transform.rotation);
        item.GetComponentInChildren<Text>().text = lists.Count.ToString();
        item.transform.parent = mContentTransform;
        lists.Add(item);

        //給每個按鈕組件監聽點擊事件
        item.onClick.AddListener(
            () =>
            {
                onClickFunc(item);
            }
        );

        //rect.sizeDelta的x是width 
        //rect.sizeDelta的y是height
        //rect.sizeDelta=new Vector2(rect.sizeDelta.x, lists.Count * itemHeight);
        rect.sizeDelta = new Vector2(rect.sizeDelta.x,
            group.padding.top + group.padding.bottom + lists.Count * itemHeight + (lists.Count - 1) * group.spacing);
        //rect.sizeDelta = new Vector2(rect.sizeDelta.x, lists.Count * itemHeight);
    }
    //使列表跳轉到頂部
    void ToTopFunc()
    {
        
        //offsetMin 是vector2(left, bottom);

        //offsetMax 是vector2(right, top);

        rect.offsetMin = new Vector2(rect.offsetMin.x,-rect.sizeDelta.y);
        rect.offsetMax = new Vector2(rect.offsetMax.x,0);

        
    }
    //使列表跳轉到底部
    void ToBottomFunc()
    {
        
        /*rect.offsetMin = new Vector2(rect.offsetMin.x, 0);
        rect.offsetMax = new Vector2(rect.offsetMax.x, rect.sizeDelta.y);*/
    }
    void onClickFunc(Button btn)
    {
        Debug.Log(btn.gameObject.GetComponent<Text>());
        removeItemFunc(btn);
    }
    //清空列表
    void ClearFunc()
    {
        for(int i = 0; i < lists.Count; i++)
        {
            Destroy(lists[i].gameObject);
        }
        lists = new List<Button>();
        rect.sizeDelta = new Vector2(rect.sizeDelta.x, lists.Count * itemHeight);
    }
    //刪除單個按鈕組件
    void removeItemFunc(Button _btn)
    {
        //因為Vertical Layout Group組件會自動排列添加上的控件,所以只需要移除場景中的物體模型和list中對象就行了
        //排列位置的任務就交給Vertical Layout Group 了

        Destroy(_btn.gameObject);

        int index = lists.IndexOf(_btn);
        lists.Remove(_btn);

        Debug.Log(lists.Count);

        //需要重置容器的height
        rect.sizeDelta = new Vector2(rect.sizeDelta.x,
            group.padding.top + group.padding.bottom + lists.Count * itemHeight + (lists.Count - 1) * group.spacing);

        //rect.sizeDelta = new Vector2(rect.sizeDelta.x, lists.Count * itemHeight);
        
        /*
        if (rect.sizeDelta.y > 1080)
        {
            
            rect.sizeDelta = new Vector2(rect.sizeDelta.x, lists.Count * itemHeight);
        }
        else
        {
            rect.sizeDelta = new Vector2(rect.sizeDelta.x, 1080);
        }*/



    }
}

用的時候只要把這個腳本隨便綁到場景中就行

另外,在重置容器的height時,兩種方法我覺得都差不多,而且在添加和刪減組件時好像都還是有些問題的,這一點在用的時候要注意

其中group關聯的是

 

PS:

rect是RectTransform
rect.sizeDelta的x是width
rect.sizeDelta的y是height

rect.offsetMin 是vector2(left, bottom);

rect.offsetMax 是vector2(right, top);

 

-----------------------------------------------------------------------------------------------------------------------------------

之前說過存在一些問題

將Content的Content Size Fitter → Vertical Fit 改為 Min Size 即可

如果是橫向滑動,則是更改 Horizontal Fit

 

如果想設置多列元素顯示,則可以將content上的Vertical Layout Group 更換成 Grid Layout Group,使用方法大致上差不多

 

有時初始顯示的滑動列表的位置可能有點不如意,這時可以通過調整

這些來改動


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM