情景,正常TextView中设置文本内容中包含中英文时会造成自动换行的问题,影响界面显示效果,如图:

网上很多解决途径,甚至有多三方框架处理,但是效果并不能达到,最终是要如下代码完美解决,效果图如下:

具体实现过程 以及代码

基本思路:先测量TextView的最大可用宽度,然后替换所有的空格符并按行分割,如果小于TextView最大宽度,则不处理;如果大于TextView最大宽度,进行单个字符进行测量,超过最大宽度则加入换行符;

public class SDAdaptiveTextView extends TextView {
public SDAdaptiveTextView(Context context) {
super(context);
} public SDAdaptiveTextView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
} public SDAdaptiveTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
} /**
* 使用该方法设置TextView的文本内容,改方法不能再主线程中执行
* @param text
*/
public void setAdaptiveText(String text) {
this.setText(text);
this.setText(adaptiveText(this));
} private String adaptiveText(final TextView textView) {
final String originalText = textView.getText().toString(); //原始文本
final Paint tvPaint = textView.getPaint();//获取TextView的Paint
final float tvWidth = textView.getWidth() - textView.getPaddingLeft() - textView.getPaddingRight(); //TextView的可用宽度
//将原始文本按行拆分
String[] originalTextLines = originalText.replaceAll("\r", "").split("\n");
StringBuilder newTextBuilder = new StringBuilder();
for (String originalTextLine : originalTextLines) {
//文本内容小于TextView宽度,即不换行,不作处理
if (tvPaint.measureText(originalTextLine) <= tvWidth) {
newTextBuilder.append(originalTextLine);
} else {
//如果整行宽度超过控件可用宽度,则按字符测量,在超过可用宽度的前一个字符处手动换行
float lineWidth = 0;
for (int i = 0; i != originalTextLine.length(); ++i) {
char charAt = originalTextLine.charAt(i);
lineWidth += tvPaint.measureText(String.valueOf(charAt));
if (lineWidth <= tvWidth) {
newTextBuilder.append(charAt);
} else {
//单行超过TextView可用宽度,换行
newTextBuilder.append("\n");
lineWidth = 0;
--i;//该代码作用是将本轮循环回滚,在新的一行重新循环判断该字符
}
}
}
}
return newTextBuilder.toString();
}
}
  • 使用 setAdaptiveText 方法替代 原生的 setText 方法,注意该方法不能再主线程中执行
  • 如果TextView宽度设置为WrapContent,为了测量它的准确宽度,可先使用setText()方法设值,再调用setAdaptiveText()设值

    举例使用:
        tvSdAdaptive.post(new Runnable() {
@Override
public void run() {
tvSdAdaptive.setAdaptiveText("");
}
});
        tvSdAdaptive.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
tvSdAdaptive.setAdaptiveText("");
tvSdAdaptive.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
});

了解更多——GitHub链接

TextView设置文字包含中英文时自动换行问题的终极解决方案的更多相关文章

  1. iOS设置文字过长时的显示格式

    以label为例: //设置文字过长时的显示格式 aLabel.lineBreakMode = UILineBreakModeMiddleTruncation; //截去中间 aLabel.lineB ...

  2. ThinkPHP+Smarty模板中截取包含中英文混合的字符串乱码的解决方案

    好几天没写博客了,其实有好多需要总结的,因为最近一直在忙着做项目,但是困惑了几天的Smarty模板中截取包含中英文混合的字符串乱码的问题,终于解决了,所以记录下来,需要的朋友看一下: 出现乱码的原因: ...

  3. textView代码设置文字居中失效 textView设置文字居中两种方法

    1.TextView的高度占据整个父控件的高度,然后设置TextView的Grayvity Center就可以了. 2.如果第一个方法不行,那么,textView的高度设置为warp_content, ...

  4. 【Android初级】使用TypeFace设置TextView的文字字体(附源码)

    在Android里面设置一个TextView的文字颜色和文字大小,都很简单,也是一个常用的基本功能.但很少有设置文字字体的,今天要分享的是通过TypeFace去设置TextView的文字字体,布局里面 ...

  5. android TextView 设置部分文字背景色和文字颜色

    通过SpannableStringBuilder来实现,它就像html里边的元素改变指定文字的文字颜色或背景色 public class MainActivity extends Activity { ...

  6. android TextView 设置部分文字背景色 和 文字颜色

    通过SpannableStringBuilder来实现,它就像html里边的元素改变指定文字的文字颜色或背景色 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ...

  7. Easyui datagrid 设置内容超过单元格宽度时自动换行显示

    datagrid 设置内容超过单元格宽度时自动换行显示 by:授客 QQ:1033553122 测试环境 jquery-easyui-1.5.3 问题描述 单元格内容超过单元格宽度不会自动化换行.如下 ...

  8. WPF 设置TextBox为空时,背景为文字提示

    WPF 设置TextBox为空时,背景为文字提示.   <TextBox FontSize="17" Height="26" Margin="2 ...

  9. vs的一些操作技巧:在写代码时自动换行的设置

    有时在写代码的时候,一行代码太长了,想换行,直接按回车键的话又会报错,怎么办?其实可以这样设置vs,就可以达到自动换行的效果啦. ​

随机推荐

  1. [方法提炼] 获取Android设备序列号方法

    通过这个方法可以检测设备是否连接成功,如果有一台或者多台设备,可以将所有设备序列号全部输出 # -*- coding:utf-8 -*- import os def attachDeviceList( ...

  2. Java链式方法

    http://blog.csdn.net/lemon_shenzhen/article/details/6358537 有两种情况可运用链式方法: 第一种  除最后一个方法外,每个方法都返回一个对象 ...

  3. BZOJ1023:[SHOI2008]cactus仙人掌图(圆方树,DP,单调队列)

    Description 如果某个无向连通图的任意一条边至多只出现在一条简单回路(simple cycle)里,我们就称这张图为仙人掌图(cactus). 所谓简单回路就是指在图上不重复经过任何一个顶点 ...

  4. Redis String类型的API使用

    package com.daxin.jedis_datastructure; import org.junit.After; import org.junit.Before; import org.j ...

  5. MongoDB逻辑操作符$or, $and,$not,$nor

    $or是一个逻辑or操作符操作在一个数据或者多个表达式并且需要选择至少一个满足条件的表达式,$or有至少以下表达式: { $or: [ { <expression1> }, { <e ...

  6. linux 的常用命令---------第十一阶段

    软件管理rpm.yum 在 windows 与 linux 之间 实现小文件传输(仅支持在 X shell 中完成文件传输,虚拟机中不可实现): # yum install  lrzsz  -y    ...

  7. ftp、ssh

    ftp.ssh都是网络传输的协议,两者一般用来访问服务器,支持ftp的服务器称为ftp服务器,支持ssh的服务器称为ssh服务器. 说白了就是不同的访问方式,ssh更加安全,有相应的密匙 https: ...

  8. Dubbo高级篇4

    https://blog.csdn.net/moonpure/article/details/52842115 线程模型 http://dubbo.io/User+Guide-zh.htm 用户指南& ...

  9. 【Codeforces 3D】Least Cost Bracket Sequence

    Codeforces 3 D 题意:有一个括号序列,其中一些位置是问号,把第\(i\)个问号改成(需要\(a_i\)的代价,把它改成)需要\(b_i\)的代价. 问使得这个括号序列成立所需要的最小代价 ...

  10. C++ 预处理器

    直接上代码 1.#define 预处理 #include <iostream> using namespace std; #define PI 3.14159 int main () { ...