步骤:
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 lists = new List();// 存放按钮组件
float itemHeight;// 单个按钮组件的height
RectTransform rect; // 容器content的rect
public VerticalLayoutGroup group;// 用于计算内容的高度
// Use this for initialization
void Start()
{
rect = mContentTransform.GetComponent();
itemHeight = mItemPrefab.GetComponent().rect.height;
ShowItems();
mScrollbar.value = 1.0f ;
}
///
/// 显示Item列表
///
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 = 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 ());
removeItemFunc(btn);
}
// 清空列表
void ClearFunc()
{
for (int i = 0 ; i < lists.Count; i++)
{
Destroy(lists[i].gameObject);
}
lists = new List();
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,使用方法大致上差不多
有时初始显示的滑动列表的位置可能有点不如意,这时可以通过调整
这些来改动