步骤:
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,使用方法大致上差不多
有时初始显示的滑动列表的位置可能有点不如意,这时可以通过调整
这些来改动