最近在一个项目中频繁出现TextView乱换行的问题,在网上找了些资料,做了下整理。废话不多说了,下面看源码。
TextView乱换行归根揭底其实是英文和中文的差异性决定的,逼近android是外国人弄出来的,风格以及规范都是按照英文来的。在TextView中每行的开头不能以中文的标
点符号以及数字开头,如果末尾是一连串的数字那你就杯具了。我的解决方法是重新TextView,这个重写的具体方法如下:
import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
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 MGAutoAlignTextView extends TextView {
private final String namespace = "http://schemas.android.com/apk/res/android";
private float textSize;
private String text;
private float paddingLeft;
private float paddingRight;
private float marginLeft;
private float marginRight;
private int textColor;
private float textShowWidth;
private Paint paint = new Paint();
public MGAutoAlignTextView(Context context, AttributeSet attrs) {
// TODO Auto-generated constructor stub
super(context,attrs);
//不知道为什么这里这样获取不到android标签的属性,郁闷,还在研究中。如果想定义间隔的话用自定义属性就可以了。
marginLeft = attrs.getAttributeIntValue(namespace, "layout_marginLeft", 15);
marginRight = attrs.getAttributeIntValue(namespace, "layout_marginRight", 15);
textColor = attrs.getAttributeIntValue(namespace, "text_color", Color.parseColor("#7d7d7d"));
}
@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
//super.onDraw(canvas);
textSize = getTextSize();
paddingLeft = getPaddingLeft();
paddingRight = getPaddingRight();
paint.setTextSize(textSize);
paint.setColor(textColor);
paint.setAntiAlias(true);
//控件宽度
textShowWidth = ((View)getParent()).getWidth() - paddingLeft - paddingRight - marginLeft - marginRight - getLineHeight();
int lineCount = 0;
text = this.getText().toString();
if(text==null)return;
char[] textCharArray = text.toCharArray();
//已绘text的宽度
float drawedWidth = 0;
//字符宽度
float charWidth;
//一个一个字符的绘制文本
for (int i = 0; i < textCharArray.length; i++) {
charWidth = paint.measureText(textCharArray, i, 1);
if(textCharArray[i]=='\n'){
lineCount++;
drawedWidth = 0;
continue;
}
if (textShowWidth - drawedWidth < charWidth) {
lineCount++;
drawedWidth = 0;
}
canvas.drawText(textCharArray, i, 1, paddingLeft + drawedWidth,
(lineCount + 1) * (getLineHeight()), paint);
drawedWidth += charWidth;
}
//设置控件高度的话会重绘界面,所以不要在onDraw里面设置界面的高度、背景颜色这些跟控件本身相关的属性,会照成死循环。
//setHeight((lineCount + 1) * (int) getLineHeight() + 5);
}
}
这里要注意的是,在onDraw里不能设置与控件相关的属性,例如高度、宽度、背景颜色等等,如果设置的话会造成死循环。
xml代码片段:
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<com.mogoo.view.MGAutoAlignTextView
android:id="@+id/mg_card_prompt_tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginLeft="12dp"
android:layout_marginRight="12dp"
android:layout_marginTop="8dp"
android:lineSpacingExtra="3dp"
android:gravity="left|center_vertical"
android:text="提示1"
android:textColor="@color/mg_color_7d7d7d"
android:textSize="@dimen/float_normal_font" />
</LinearLayout>
上面的代码可能大家在其他地方也看过,我这里是引用前辈的代码稍微调整了一些。