在使用TextView显示字符串的时候,有时候会遇到一些字符莫名就自动的换行,
这样看起来就很不爽了。
一、原因
-
半角字符与全角字符混乱所致:这种情况一般就是汉字与数字、英文字母混用
-
全角/半角标点符号出现在行首时,该标点符号会连同其前一个字符跳到下一行
-
英文单词不能被折成两行
二、解决
- 将textview中的字符全角化。即将所有的数字、字母及标点全部转为全角字符,使它们与汉字同占两个字节,这样就可以避免由于占位导致的排版混乱问题了。
public static String toDBC(String input) {
char[] c = input.toCharArray();
for (int i = 0; i < c.length; i++) {
if (c[i] == 12288) {
// 全角空格为12288,半角空格为32
c[i] = (char) 32;
continue;
}
if (c[i] > 65280 && c[i] < 65375)
// 其他字符半角(33-126)与全角(65281-65374)的对应关系是:均相差65248
c[i] = (char) (c[i] - 65248);
}
return new String(c);
}
- 重写TextView来自定义自己的文本。
public class JustifyTextView extends TextView {
public JustifyTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
}
@Override
protected void onDraw(Canvas canvas) {
TextPaint mPaint = getPaint();
Paint.FontMetrics fm = mPaint.getFontMetrics();
float baseline = fm.descent - fm.ascent;
float x = 0;
//由于系统基于字体的底部来绘制文本,所有需要加上字体的高度。
float y = baseline;
String txt = this.getText().toString();
//文本自动换行
String[] texts = autoSplit(txt, mPaint, getWidth() - 5);
Log.d( Arrays.toString(texts));
for(String text : texts) {
//坐标以控件左上角为原点
canvas.drawText(text, x, y, mPaint);
//添加字体行间距
y += baseline + fm.leading;
}
}
private boolean isFirstLineOfParagraph(int lineStart, String line) {
return line.length() > 3 && line.charAt(0) == ' ' && line.charAt(1) == ' ';
}
/**
* 分割文本
* @param content 文本内容
* @param p 画笔,用来根据字体测量文本的宽度
* @param width 最大的可显示像素(一般为控件的宽度)
* @return 一个字符串数组,保存每行的文本
*/
private String[] autoSplit(String content, Paint p, float width) {
int length = content.length();
float textWidth = p.measureText(content);
if(textWidth <= width) {
return new String[]{content};
}
List<String> result = Lists.newArrayList();
int start = 0, end = 1;
while(start < length) {
if(p.measureText(content, start, end) >= width) {
//文本宽度超出控件宽度时
result.add(content.substring(start, end));
start = end;
}
if(end == length) {
//不足一行的文本
result.add(content.substring(start, end));
break;
}
end += 1;
}
return result.toArray(new String[0]);
}
private boolean needScale(String line) {
if (line.length() == 0) {
return false;
} else {
return line.charAt(line.length() - 1) != '\n';
}
}
}