一、要达到的效果
- 收纳功能:点击【步骤名称】,弹出【详细步骤页面】,再次点击则收纳该页面
- 更多步骤自适应:【详细步骤页面】里面的小步骤可以随意添加,沿垂直方向等距离布局
- 拖拽滑动显示:【详细步骤页面】可以用鼠标拖拽,上下滑动进行浏览
二、实现过程
本步难点:详细步骤可多可少,这些步骤沿着垂直方向等距离布局
要实现的功能 | 用什么组件 | ||
---|---|---|---|
1 | 如何实现窗口滚动 | ScrollView | |
2 | 详细步骤动态添加后自动垂直排布 | Vertical Layout Group | |
3* | 为什么【Content组件的Tect Transform】不会在垂直方向伸展 | Content Size Fitter | 垂直自适应 |
上面的第3步极为关键
【Vertical Layout Group】和【Content Size Fitter】组建的参数设置:
/// <summary>
/// 设置VerticalLayoutGroup与ContentSizeFitter组件的属性
/// </summary>
public void InitContentComponent()
{
//添加 Vertical Layout Group 组件,并设置为自动布局
if (content.GetComponent<VerticalLayoutGroup>() == null) content.gameObject.AddComponent<VerticalLayoutGroup>();
VerticalLayoutGroup layoutGroup = content.GetComponent<VerticalLayoutGroup>();
layoutGroup.childControlHeight = true;
layoutGroup.childForceExpandHeight = false;
layoutGroup.spacing = spacing; // 设置新的 Text 对象的间距
//添加ContentSizeFitter组件,内容自适应
if (content.GetComponent<ContentSizeFitter>() == null) content.gameObject.AddComponent<ContentSizeFitter>();
var contentFiter = content.GetComponent<ContentSizeFitter>();
contentFiter.verticalFit = ContentSizeFitter.FitMode.PreferredSize; // 将 Vertical Fit 设置为 Preferred Size
}
三、脚本及代码
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public class ScrollViewTexts : MonoBehaviour
{
/// <summary>
/// scrollView的Content对象
/// </summary>
[Header("scrollView的Content对象")]
[SerializeField]
public RectTransform content;
/// <summary>
/// 用来实例化的text对象
/// </summary>
[Header("用来实例化的text对象")]
[SerializeField]
public GameObject textPrefab;
/// <summary>
/// 垂直布局时,item之间的间距
/// </summary>
[Header("文本的行间距")]
[SerializeField]
public float spacing = 1f;
void Start()
{
InitContentComponent();
}
/// <summary>
/// 设置VerticalLayoutGroup与ContentSizeFitter组件的属性
/// </summary>
public void InitContentComponent()
{
//添加 Vertical Layout Group 组件,并设置为自动布局
if (content.GetComponent<VerticalLayoutGroup>() == null) content.gameObject.AddComponent<VerticalLayoutGroup>();
VerticalLayoutGroup layoutGroup = content.GetComponent<VerticalLayoutGroup>();
layoutGroup.childControlHeight = true;
layoutGroup.childForceExpandHeight = false;
layoutGroup.spacing = spacing; // 设置新的 Text 对象的间距
//添加ContentSizeFitter组件,内容自适应
if (content.GetComponent<ContentSizeFitter>() == null) content.gameObject.AddComponent<ContentSizeFitter>();
var contentFiter = content.GetComponent<ContentSizeFitter>();
contentFiter.verticalFit = ContentSizeFitter.FitMode.PreferredSize; // 将 Vertical Fit 设置为 Preferred Size
}
/// <summary>
/// 添加新的Text文本
/// </summary>
/// <param name="text">文本的内容</param>
/// <returns>text对象</returns>
public GameObject AddText(string text)
{
// 创建新的 Text 对象
GameObject newText = Instantiate(textPrefab, content);
// 设置 Text 组件的文本内容
newText.GetComponent<TMP_Text>().text = text;
// 添加 ContentSizeFitter 组件,并设置为 VerticalFitMode.PreferredSize
ContentSizeFitter sizeFitter = newText.AddComponent<ContentSizeFitter>();
sizeFitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
// 重新计算布局
LayoutRebuilder.ForceRebuildLayoutImmediate(content);
return newText;
}
[Header("文本内容-测试用")]
[SerializeField]
public string text;
#if UNITY_EDITOR
[ContextMenu("测试")]
#endif
void Test()
{
AddText(text);
}
}