TextView 自动换行导致文字排版参差不齐的原因



Android TextView的自动换行会导致文本排版参差不齐,大概原因如下:

一:全角字符和半角字符混乱使用

常见于汉字字符和数字、英文字符混合使用。

解决办法:

将text中的字符全角化,即将所有的数字、字母、标点符号全部转为全角字符,

使他们同汉字一样占用两个字节,这样就可以避免由于占位混乱导致的排版混乱问题,转换代码如下:

public static String ToDBC(String input) {  
   char[] c = input.toCharArray();  
   for (int i = 0; i< c.length; i++) {  
       if (c[i] == 12288) {  
         c[i] = (char) 32;  
         continue;  
       }if (c[i]> 65280&& c[i]< 65375)  
          c[i] = (char) (c[i] - 65248);  
       }  
   return new String(c);  
}  


二:全角字符和半角字符混乱使用

TextView在显示中文的时候标点符号不能显示在一行的行首和行尾,如果一个标点符号刚好在一行的行尾,

该标点符号就会连同前一个字符自动换到下一行显示。

解决办法:

在该标点符号后面添加一个空格。


三:一个英文单词不能被显示在两行中

TextView在显示英文时,标点符号是可以放在行尾的,但英文单词不能分开。


两行对齐:实现两行对齐的显示效果

解决办法一:

修改Android源代码;将frameworks/base/core/java/android/text下的StaticLayout.java文件中的如下代码 去掉:

  if (c == ' ' || c == '/t' ||
                            ((c == '.'  || c == ',' || c == ':' || c == ';') &&
                             (j - 1 < here || !Character.isDigit(chs[j - 1 - start])) &&
                             (j + 1 >= next || !Character.isDigit(chs[j + 1 - start]))) ||
                            ((c == '/' || c == '-') &&
                             (j + 1 >= next || !Character.isDigit(chs[j + 1 - start]))) ||
                            (c >= FIRST_CJK && isIdeographic(c, true) &&
                             j + 1 < next && isIdeographic(chs[j + 1 - start], false))) {
                            okwidth = w;
                            ok = j + 1;

                            if (fittop < oktop)
                                oktop = fittop;
                            if (fitascent < okascent)
                                okascent = fitascent;
                            if (fitdescent > okdescent)
                                okdescent = fitdescent;
                            if (fitbottom > okbottom)
                                okbottom = fitbottom;
                        }
去掉后标点符号可以显示在行首和行尾,英文单词也可以被分开在两行中显示。

解决办法二:

package rong.android.test;

import org.json.JSONArray;
import org.json.JSONException;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
import android.widget.TextView;

public class XRTextView extends TextView{
	
	private final String namespace = "rong.android.TextView";
	private String text;
	private float textSize;
	private float paddingLeft;
	private float paddingRight;
	private float marginLeft;
	private float marginRight;
	private int textColor;
	private JSONArray colorIndex;
	private Paint paint1 = new Paint();
	private Paint paintColor = new Paint();
	private float textShowWidth;
	private float Spacing = 0;
	private float LineSpacing = 1.3f;//行与行的间距
	
	public XRTextView(Context context, AttributeSet attrs) {
		super(context, attrs);
		text = attrs.getAttributeValue(
				"http://schemas.android.com/apk/res/android", "text");
		textSize = attrs.getAttributeIntValue(namespace, "textSize", 25);//字体大小
		textColor = attrs.getAttributeIntValue(namespace, "textColor",Color.BLUE);//字体颜色
		paddingLeft = attrs.getAttributeIntValue(namespace, "paddingLeft", 0);
		paddingRight = attrs.getAttributeIntValue(namespace, "paddingRight", 0);
		marginLeft = attrs.getAttributeIntValue(namespace, "marginLeft", 0);
		marginRight = attrs.getAttributeIntValue(namespace, "marginRight", 0);
		paint1.setTextSize(textSize);
		paint1.setColor(textColor);
		paint1.setAntiAlias(true);
		paintColor.setAntiAlias(true);
		paintColor.setTextSize(textSize);
		paintColor.setColor(Color.BLUE);
	}
	
	public XRTextView(Context context, float textSize, int textColor, 
			float paddingLeft, float paddingRight, float marginLeft, float marginRight){
		super(context);
		this.textSize = textSize;
		this.textColor = textColor;
		this.paddingLeft = paddingLeft;
		this.paddingRight = paddingRight;
		this.marginLeft = marginLeft;
		this.marginRight = marginRight;
		paint1.setTextSize(textSize);
		paint1.setColor(textColor);
		paint1.setAntiAlias(true); 
		paintColor.setAntiAlias(true);
		paintColor.setTextSize(textSize);
		paintColor.setColor(Color.BLUE);
	}

	
	public JSONArray getColorIndex() {
		return colorIndex;
	}

	public void setColorIndex(JSONArray colorIndex) {
		this.colorIndex = colorIndex;
	}
	/**
	 * 传入一个索引,判断当前字是否被高亮
	 * @param index
	 * @return
	 * @throws JSONException 
	 */
	public boolean isColor(int index) throws JSONException{
		if(colorIndex == null){
			return false;
		}
		for(int i = 0 ; i < colorIndex.length() ; i ++){
			JSONArray array = colorIndex.getJSONArray(i);
			int start = array.getInt(0);
			int end = array.getInt(1)-1;
			if(index >= start && index <= end){
				return true;
			}
			
		}
		
		
		return false;
	}
	

	@Override
	protected void onDraw(Canvas canvas) {
//		super.onDraw(canvas);
		View view=(View)this.getParent();
		textShowWidth=view.getMeasuredWidth() - paddingLeft - paddingRight - marginLeft - marginRight;
		int lineCount = 0;
		
		text = this.getText().toString();//.replaceAll("\n", "\r\n");
		if(text==null)return;
		char[] textCharArray = text.toCharArray();
		// 已绘的宽度
		float drawedWidth = 0;
		float charWidth;
		for (int i = 0; i < textCharArray.length; i++) {
			charWidth = paint1.measureText(textCharArray, i, 1);
			
			if(textCharArray[i]=='\n'){
				lineCount++;
				drawedWidth = 0;
				continue;
			}
			if (textShowWidth - drawedWidth < charWidth) {
				lineCount++;
				drawedWidth = 0;
			}
			boolean color = false;
			try {
				color = isColor(i);
			} catch (JSONException e1) {
				e1.printStackTrace();
			}
			
			if(color){
				
				canvas.drawText(textCharArray, i, 1, paddingLeft + drawedWidth,
						(lineCount + 1) * textSize * LineSpacing, paintColor);
			}else{
				
				canvas.drawText(textCharArray, i, 1, paddingLeft + drawedWidth,
						(lineCount + 1) * textSize * LineSpacing, paint1);
			}
			if(textCharArray[i] > 127 && textCharArray[i] != '、' 
					&& textCharArray[i] != ',' && textCharArray[i] != '。' 
					&& textCharArray[i] != ':' && textCharArray[i] != '!'){
				drawedWidth += charWidth + Spacing;
				
			}else{
				drawedWidth += charWidth;

			}
		}
		setHeight((int) ((lineCount + 1) * (int) textSize * LineSpacing + 10));
	}
	public float getSpacing() {
		return Spacing;
	}
	public void setSpacing(float spacing) {
		Spacing = spacing;
	}
	public float getMYLineSpacing() {
		return LineSpacing;
	}
	public void setMYLineSpacing(float lineSpacing) {
		LineSpacing = lineSpacing;
	}
	public float getMYTextSize() {
		return textSize;
	}
	public void setMYTextSize(float textSize) {
		this.textSize = textSize;
		paint1.setTextSize(textSize);
		paintColor.setTextSize(textSize);
	}
	
	
}















  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值