UGUI 标签流(流式布局)

    xiaoxiao2021-03-25  96

    目的:

    今天要做一个基于UGUI标签流的功能的文档。标签流的作用在于:在日常的App中,时常会涉及到对热门、推荐等标签自动换行的流式布局。常用于关键词搜索或者热门标签等场景

    类似于下面:

    流式布局的原理:当某一行的空间不足容纳新的内容时,自动向下一行移动

    如下:

          

    所涉及到的重点:

    (1)通过字体及字符串Length,获取字符串所占Text长度(显示的像素) (2)计算当前行剩余空间是否能容纳下一个标签

    代码如下所示:

    1:通过字体及字符串长度获取字符串显示长度:

        /// <summary>     /// 通过字体及字符串长度获取某字符串显示长度(像素)     /// </summary>     /// <param name="fontsize">字号</param>     /// <param name="text">内容</param>     /// <param name="fontStyle">字体类型(普通、加粗、倾斜)</param>     /// <param name="path">字体路径</param>     /// <returns></returns>     float GetTextWidth(int fontsize,string text,FontStyle fontStyle,string path)     {         Font font = Resources.Load<Font>(path);         font.RequestCharactersInTexture(text, fontsize, fontStyle);         CharacterInfo characterInfo;         float width = 0f;         for (int i = 0; i < text.Length; i++)         {             font.GetCharacterInfo(text[i], out characterInfo, fontsize);             width += characterInfo.advance;         }         return width;     }

    2:通过克隆并显示一个Button

    /// <summary>     /// 通过克隆并显示一个Button     /// </summary>     /// <param name="ContentText">Button文字</param>     /// <param name="objParent">初始化后Button的父物体(容纳的Box)</param>     /// <param name="info">字符串相关信息(字号、字体、类型、路径等)</param>     /// <returns></returns>     GameObject GetInitButton(string ContentText,Transform objParent,OriginInfo info)     {         var textWidth = GetTextWidth(info._fontsize, ContentText, info._fontStyle, info._fontPath);         var btn = (GameObject)Object.Instantiate(Resources.Load(info._btnResPath));         btn.transform.SetParent(objParent);         btn.GetComponent<RectTransform>().sizeDelta = new Vector2(textWidth + info._addRect.x, info._addRect.y);         btn.GetComponentInChildren<UnityEngine.UI.Text>().text = ContentText;         btn.transform.localScale = Vector3.one;         return btn;     }

    3:标签流显示

    /// <summary>     /// 标签流展示     /// </summary>     /// <param name="labelFlowOrignInfo"></param>     /// <param name="contentList">字符串列表(所要展示的Button流)</param>     /// <param name="objParent"></param>     /// <param name="info"></param>     public  void LabelFlowShow(LabelFlowOrigin labelFlowOrignInfo, List<string> contentList,Transform objParent,OriginInfo info)     {         labelFlowOrignInfo._totalLength = labelFlowOrignInfo._paddingLeft;         var parentWidth = objParent.GetComponent<RectTransform>().sizeDelta.x;//当父物体没有做拉伸时         for (int i = 0; i < contentList.Count; i++)         {             //Initialization button             var objButton = GetInitButton(contentList[i], objParent,info);             var objButtonRect = objButton.GetComponent<RectTransform>();             //Control button postion             if (labelFlowOrignInfo._totalLength + objButtonRect.sizeDelta.x + labelFlowOrignInfo._paddingRight > parentWidth)             {                 labelFlowOrignInfo._totalLength = labelFlowOrignInfo._paddingLeft;                 labelFlowOrignInfo._rows++;             }             objButton.GetComponent<RectTransform>().localPosition = new Vector3(labelFlowOrignInfo._totalLength, -labelFlowOrignInfo._spacingVertical * labelFlowOrignInfo._rows - objButtonRect.sizeDelta.y * (labelFlowOrignInfo._rows - 1), 0);             labelFlowOrignInfo._totalLength += objButtonRect.sizeDelta.x + labelFlowOrignInfo._spacingHorizontal;         }     }

    4:两个类用于代码管理

    /// <summary> /// 两个类用于代码管理 /// </summary> public class LabelFlowOrigin {     public float _paddingLeft;//左边距     public float _paddingRight;//右边距     public float _paddingUp;//上边距     public float _spacingHorizontal;//行间距     public float _spacingVertical;//列间距     public float _totalLength;//某行的当前长度     public int _rows;//第几行     public LabelFlowOrigin(float paddingLeft, float paddingRight, float paddingUp, float spacingHorizonta, float spacingVertical, float totalLength, int rows)     {         this._paddingLeft = paddingLeft;         this._paddingRight = paddingRight;         this._paddingUp = paddingUp;         this._spacingHorizontal = spacingHorizonta;         this._spacingVertical = spacingVertical;         this._totalLength = totalLength;         this._rows = rows;     } } public  class OriginInfo {     public int _fontsize;//字号     public FontStyle _fontStyle;//类型     //Button的显示(x——Button背景比字符串本身左右宽多少长度,y——Button高度)     public Vector2 _addRect;     public string _fontPath;//字体路径     public string _btnResPath;//Button预制体路径     public OriginInfo(int fontsize, FontStyle fontStyle, Vector2 addRect, string fontPath, string btnResPath)     {         this._fontPath = fontPath;         this._fontStyle = fontStyle;         this._fontsize = fontsize;         this._addRect = addRect;         this._btnResPath = btnResPath;     } }

    全部代码如下所示:

    using UnityEngine; using System.Collections; using System.Collections.Generic; /// <summary> /// 标签流——Made By XXQQ /// </summary> public class InitLabelFlow {     #region    singleton     static InitLabelFlow instance = null;     public static InitLabelFlow Instance     {         get         {             if (instance == null)                 instance = new InitLabelFlow();             return instance;         }     }     #endregion;     /// <summary>     /// 通过字体及字符串长度获取某字符串显示长度(像素)     /// </summary>     /// <param name="fontsize">字号</param>     /// <param name="text">内容</param>     /// <param name="fontStyle">字体类型(普通、加粗、倾斜)</param>     /// <param name="path">字体路径</param>     /// <returns></returns>     float GetTextWidth(int fontsize,string text,FontStyle fontStyle,string path)     {         Font font = Resources.Load<Font>(path);         font.RequestCharactersInTexture(text, fontsize, fontStyle);         CharacterInfo characterInfo;         float width = 0f;         for (int i = 0; i < text.Length; i++)         {             font.GetCharacterInfo(text[i], out characterInfo, fontsize);             width += characterInfo.advance;         }         return width;     }     /// <summary>     /// 通过克隆并显示一个Button     /// </summary>     /// <param name="ContentText">Button文字</param>     /// <param name="objParent">初始化后Button的父物体(容纳的Box)</param>     /// <param name="info">字符串相关信息(字号、字体、类型、路径等)</param>     /// <returns></returns>     GameObject GetInitButton(string ContentText,Transform objParent,OriginInfo info)     {         var textWidth = GetTextWidth(info._fontsize, ContentText, info._fontStyle, info._fontPath);         var btn = (GameObject)Object.Instantiate(Resources.Load(info._btnResPath));         btn.transform.SetParent(objParent);         btn.GetComponent<RectTransform>().sizeDelta = new Vector2(textWidth + info._addRect.x, info._addRect.y);         btn.GetComponentInChildren<UnityEngine.UI.Text>().text = ContentText;         btn.transform.localScale = Vector3.one;         return btn;     }     /// <summary>     /// 标签流显示     /// </summary>     /// <param name="labelFlowOrignInfo"></param>     /// <param name="contentList">字符串列表(所要展示的Button流)</param>     /// <param name="objParent"></param>     /// <param name="info"></param>     public  void LabelFlowShow(LabelFlowOrigin labelFlowOrignInfo, List<string> contentList,Transform objParent,OriginInfo info)     {         labelFlowOrignInfo._totalLength = labelFlowOrignInfo._paddingLeft;         var parentWidth = objParent.GetComponent<RectTransform>().sizeDelta.x;//当父物体没有做拉伸时         for (int i = 0; i < contentList.Count; i++)         {             //Initialization button             var objButton = GetInitButton(contentList[i], objParent,info);             var objButtonRect = objButton.GetComponent<RectTransform>();             //Control button postion             if (labelFlowOrignInfo._totalLength + objButtonRect.sizeDelta.x + labelFlowOrignInfo._paddingRight > parentWidth)             {                 labelFlowOrignInfo._totalLength = labelFlowOrignInfo._paddingLeft;                 labelFlowOrignInfo._rows++;             }             objButton.GetComponent<RectTransform>().localPosition = new Vector3(labelFlowOrignInfo._totalLength, -labelFlowOrignInfo._spacingVertical * labelFlowOrignInfo._rows - objButtonRect.sizeDelta.y * (labelFlowOrignInfo._rows - 1), 0);             labelFlowOrignInfo._totalLength += objButtonRect.sizeDelta.x + labelFlowOrignInfo._spacingHorizontal;         }     } } /// <summary> /// 两个类用于代码管理 /// </summary> public class LabelFlowOrigin {     public float _paddingLeft;//左边距     public float _paddingRight;//右边距     public float _paddingUp;//上边距     public float _spacingHorizontal;//行间距     public float _spacingVertical;//列间距     public float _totalLength;//某行的当前长度     public int _rows;//第几行     public LabelFlowOrigin(float paddingLeft, float paddingRight, float paddingUp, float spacingHorizonta, float spacingVertical, float totalLength, int rows)     {         this._paddingLeft = paddingLeft;         this._paddingRight = paddingRight;         this._paddingUp = paddingUp;         this._spacingHorizontal = spacingHorizonta;         this._spacingVertical = spacingVertical;         this._totalLength = totalLength;         this._rows = rows;     } } public  class OriginInfo {     public int _fontsize;//字号     public FontStyle _fontStyle;//类型     //Button的显示(x——Button背景比字符串本身左右宽多少长度,y——Button高度)     public Vector2 _addRect;     public string _fontPath;//字体路径     public string _btnResPath;//Button预制体路径     public OriginInfo(int fontsize, FontStyle fontStyle, Vector2 addRect, string fontPath, string btnResPath)     {         this._fontPath = fontPath;         this._fontStyle = fontStyle;         this._fontsize = fontsize;         this._addRect = addRect;         this._btnResPath = btnResPath;     } } 标签流测试用例 using UnityEngine; using System.Collections; using System.Collections.Generic; /// <summary> /// 标签流测试用例 /// </summary> public class Test : MonoBehaviour {     void Start()     {         var labelFlowOrigin = new LabelFlowOrigin(10, 10, 0, 30, 30, 0, 1);         List<string> contentList = new List<string>() { "跪下,叫爸爸!", "我是Bruce", "XXQQ", "今天的天气哈哈哈", "落霞与孤鹜齐飞", "Smiles Of Roses","我在马路边捡到一分钱","震惊——" };         var parent = GameObject.Find("Image").transform;         var originInfo = new OriginInfo(24, FontStyle.Normal, new Vector2(60, 50), "font/DroidSansFallback", "XQResources/CollectionButton");         InitLabelFlow.Instance.LabelFlowShow(labelFlowOrigin, contentList, parent, originInfo);     } }

    实用效果:

    转载请注明原文地址: https://ju.6miu.com/read-23477.html

    最新回复(0)