android settext内容换行_TextView设置文字包含中英文时自动换行问题的终极解决方案...

博客针对Android中TextView设置包含中英文文本时自动换行影响界面效果的问题,给出解决方案。基本思路是测量TextView最大可用宽度,按行分割文本,根据宽度判断是否添加换行符。提供了具体代码及使用方法,还给出了宽度为WrapContent时的处理示例。

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

情景,正常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);

}

});

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值