聊天界面: 表情和文字自适应

本文探讨了如何在聊天界面中实现表情和文字的自适应布局,以此模仿微信等流行聊天应用的功能。重点讲述在聊天记录滚动至底部时,保持最新消息可见的实现方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近在做聊天,样式是模仿微信的。

滚动到最下面显示最新的聊天记录,在上一篇博文已经讲解。

今天说哈: 表情和文字自适应的问题

 

using System;
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Text.RegularExpressions;


using System.Linq;
using System.Text;
using Assets.maintank.scripts.vos;
using Assets.sharecode.core.controller;
using Assets.sharecode.core.evt;
using Assets.sharecode.core.req;
using LitJson;


using Assets.sharecode.core.ui;
using Assets.sharecode.core.view;

using Assets.maintank.scripts.controllers.leader.controlVo;
using Assets.maintank.scripts.views.lead;
using Assets.maintank.scripts.vos.commander;

using Assets.maintank.scripts.views.active;

using Assets.maintank.scripts.vos.activity;

public class ChatLoginfoCom : MonoBehaviour
{

    int maxHangju = 5;

    bool isHaveFace=false;// 有没有表情,有表情行行间距不一样

    public int faceWidth = 50;// 表情宽度
    
    //背景的高度
    public int cellHeight = 50;
    /// <summary>
    /// 这句话最大宽度 否则换行
    /// </summary>
    public int MaxLineWidth = 400;


    /// <summary>
    /// 这句话最大宽度 否则换行
    /// </summary>
    public int maxWidth = 400;
    /// <summary>
    ///  默认第一个表情或者文字位置 X
    /// </summary>
    private int vPosx ;
    private int vPosy;


    public GameObject FacePrefab;

    public GameObject Label;

    /// <summary>
    /// 聊天说的话
    /// </summary>
    private string m_text;

    //背景
    private UISprite back;

    /// <summary>
    /// 解析后表情和文字后的数组进行创建
    /// </summary>
    private static List<LabelType> list = new List<LabelType>();

    public enum InfoType
    {
        Text,
        Face,
    }

    public class LabelType
    {
        public string info;
        public InfoType type;

        public LabelType(string text, InfoType tp)
        {
            info = text;
            type = tp;
        }
    }


    private int positionX = 7;
    private int positionY = 0;

    //label缓存区
    private List<UILabel> labelCaches = new List<UILabel> ();

    //label当前使用的数据
    private List<UILabel> labelCur = new List<UILabel>();

    //表情缓存区
    private List<GameObject> prefabCeches = new List<GameObject>();

    //当前使用的数据
    private List<GameObject> prefabCur = new List<GameObject>();

    /// <summary>
    /// 这句话的宽度
    /// </summary>
    int maxWeight = 0;
    /// <summary>
    /// 在每一行的末尾加的宽度 好看而已
    /// </summary>
    int addValue = 0;

    bool isUser = true;
    /// <summary>
    /// 默认我的话  true 我的话 false 别人的话
    /// </summary
    public bool isWhtichUser
    {
        set
        {
            isUser = value;
        }
    }


    /// <summary>
    /// 每行末尾的空格 好看而已
    /// </summary>
    public int addvalue
    {
        set
        {
            addValue = value;
        }
    }
    /// <summary>
    /// 第一个lable的初始位置x
    /// </summary>
    public int posx
    {
        set
        {
            vPosx = value;
        }
    }
    public int posy
    {
        set
        {
            vPosy = value;
        }
    }

    /// <summary>
    /// 文本内容
    /// </summary>
    public string text
    {
        get
        {
            return m_text;
        }
        set
        {

            back = transform.GetComponent<UISprite>();

            cellHeight = 20;

            m_text = value;

            Reset();

            ParseSymbol(value);

            ShowSymbol(list);

            if (maxWeight != 0)
            {
                back.width = maxWeight + addValue;
            }
            else
            {

                back.width = positionX+ addValue;
            }

            NGUITools.UpdateWidgetCollider(back.gameObject);

           

            if (isUser)
            {
                Vector3 p = back.transform.localPosition;
                back.transform.localPosition = new Vector3(p.x - back.width-10, p.y, p.z);
            }
        }
    }
    /// <summary>
    /// 清空数据
    /// </summary>
    private void Reset()
    {
        positionX = vPosx;
        positionY = vPosy;
        list.Clear();
        while (labelCur.Count > 0)
        {
            UILabel lab = labelCur[0];

            labelCur.Remove(lab);
            labelCaches.Add(lab);
            lab.gameObject.SetActive(false);
        }

        while (prefabCur.Count > 0)
        {
            GameObject go = prefabCur[0];

            prefabCur.Remove(go);
            prefabCeches.Add(go);
            go.SetActive(false);
        }
    }
    /// <summary>
    /// 解析字符串--- 文字或者汉字 到数组里 进行创建
    /// </summary>
    /// <param name="value"></param>
    private static void ParseSymbol(string value)
    {
        if (string.IsNullOrEmpty(value))
            return;

        int startIndex = 0;
        int endIndex = 0;
        string startString;
        string endString = value;

        string pattern = "\\{\\d\\d*\\}";
        MatchCollection matchs = Regex.Matches(value, pattern);
        string str;

        if (matchs.Count > 0)
        {
            foreach (Match item in matchs)
            {
                str = item.Value;
                startIndex = endString.IndexOf(str);
                endIndex = startIndex + str.Length;

                if (startIndex > -1)
                {
                    startString = endString.Substring(0, startIndex);

                    if (!string.IsNullOrEmpty(startString))
                        list.Add(new LabelType(startString, InfoType.Text));

                    if (!string.IsNullOrEmpty(str))
                        list.Add(new LabelType(str, InfoType.Face));

                    endString = endString.Substring(endIndex);
                }
            }

            if (!string.IsNullOrEmpty(endString))
                list.Add(new LabelType(endString, InfoType.Text));
        }
        else
        {
            list.Add(new LabelType(endString, InfoType.Text));
        }
    }
    /// <summary>
    /// 创建文字+表情
    /// </summary>
    /// <param name="list"></param>
    private void ShowSymbol(List<LabelType> list)
    {
        foreach (LabelType item in list)
        {
            switch (item.type)
            {
                case InfoType.Text:
                    CreateTextLabel(item.info);
                    break;
                case InfoType.Face:
                    CreateFace(item.info);
                    break;
            }
        }
    }
    /// <summary>
    /// 创建文字
    /// </summary>
    /// <param name="value"></param>
    private void CreateTextLabel(string value)
    {

        UILabel label;
        if (labelCaches.Count > 0)
        {
            label = labelCaches[0];
            labelCaches.Remove(label);
            label.gameObject.SetActive(true);
        }
        else
        {
            GameObject go = GameObject.Instantiate(Label) as GameObject;

            go.transform.parent = transform;
            label = go.GetComponent<UILabel>();
            go.transform.localScale = Vector3.one;
        }
        label.gameObject.SetActive(true);
        string sbstr = "";

        string word = "";

        NGUIText.fontSize = label.fontSize;
        NGUIText.finalSize = label.fontSize;
        NGUIText.dynamicFont = label.trueTypeFont;
        NGUIText.rectWidth = maxWidth;
        NGUIText.maxLines = 10000;
        NGUIText.rectHeight = 10000;

        NGUIText.WrapText(value, out sbstr);

        int index = sbstr.IndexOf("\n");

        if (index > -1)
        {
            word = sbstr.Substring(0, index);
        }
        else
        {
            word = sbstr;
        }

        label.text = word ;

        label.gameObject.transform.localPosition = new Vector3(positionX, positionY, 0);

        positionX += label.width;

        labelCur.Add(label);


        sbstr = sbstr.Remove(0, word.Length);


       int valuew = isHaveFace ? faceWidth : cellHeight; 


        if (sbstr.Length > 0)
        {

            maxWeight = positionX;
            positionX = vPosx;

            positionY -= valuew + maxHangju;
            back.height += valuew + maxHangju;

            sbstr = sbstr.Replace("\n", "");
            CreateTextLabel(sbstr);
        }
    }

    string GetIcon(string icon)
    {
        return "ICON_2_";
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="value"></param>
    private void CreateFace(string value)
    {
        isHaveFace = true;

        GameObject face;

        UIWidget widget;

        if (prefabCeches.Count > 0)
        {
            face = prefabCeches[0];
            prefabCeches.Remove(face);
            face.SetActive(true);
        }
        else
        {
            face = GameObject.Instantiate(FacePrefab) as GameObject;

            face.transform.parent = gameObject.transform;
            face.transform.localScale = FacePrefab.transform.localScale;
        }
        face.gameObject.SetActive(true);

        UISprite sprite = face.GetComponent<UISprite>();



        FaceVo vo = AllCommanderFaceConfigInfo.gettypVO(value);

        string name = vo.icon;


        sprite.spriteName = name;



        //UISpriteAnimation aim = face.GetComponent<UISpriteAnimation>();
        //aim.namePrefix = name;


        widget = face.GetComponent<UIWidget>();
        widget.pivot = UIWidget.Pivot.TopLeft;


        if (maxWidth < (positionX))
        {
            maxWeight = positionX;
            positionX = vPosx;
            positionY -= faceWidth+ maxHangju;
            back.height += faceWidth + maxHangju;
        }

        face.transform.localPosition = new Vector3(positionX, positionY+10, 0);


        positionX += faceWidth;

        prefabCur.Add(face);

    }

  
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值