您的位置:首页 > 移动开发 > Android开发

解决android系统TextView自动换行不美观问题

2013-04-15 10:48 531 查看
转发至:http://www.cnblogs.com/baiyongquan/archive/2012/06/27/2566167.html

android系统中的textview会在行尾是连串的数字、字母或者标点符号时提前换行,其实word中也是会提前换行的,但是PC端毕竟字符占的空间比例比较小,手机字符占的比例就很大,所以有时候系统自带textview显示行尾会有很大的空白比例,非常难看。所以我们在这种情况下有必要做一个控件用来显示文本。

public class AutoBreakTextView extends TextView {

public static int m_iTextHeight; // 文本的高度

public static int m_iTextWidth;// 文本的宽度

private Paint mPaint = null;

private String string = "";

private float LineSpace = 0;// 行间距

private int padding;

public AutoBreakTextView(Context context, AttributeSet set) {

super(context, set);

WindowManager manager = (WindowManager) context

.getSystemService(Context.WINDOW_SERVICE);

DisplayMetrics dm = new DisplayMetrics();

manager.getDefaultDisplay().getMetrics(dm);

System.out.println("width------>" + dm.widthPixels);

System.out.println("density-------------->" + dm.density);

m_iTextWidth = (int) (dm.widthPixels - 2 * padding - (10 * 4 * dm.density)) + 1;

float textSize = this.getTextSize();

padding = this.getPaddingLeft();

System.out.println("width------------>" + m_iTextWidth);

System.out.println("textSize------------>" + textSize);

mPaint = new Paint();

mPaint.setAntiAlias(true);

mPaint.setTextSize(textSize);

mPaint.setColor(Color.GRAY);

}

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

char ch;

int w = 0;

int istart = 0;

int m_iFontHeight;

int m_iRealLine = 0;

int x = padding;

int y = padding;

Vector m_String = new Vector();

FontMetrics fm = mPaint.getFontMetrics();

m_iFontHeight = (int) Math.ceil(fm.descent - fm.top) + (int) LineSpace;// 计算字体高度(字体高度+行间距)

for (int i = 0; i < string.length(); i++) {

ch = string.charAt(i);

float[] widths = new float[1];

String srt = String.valueOf(ch);

mPaint.getTextWidths(srt, widths);

if (ch == '\n') {

m_iRealLine++;

m_String.addElement(string.substring(istart, i));

istart = i + 1;

w = 0;

} else {

w += (int) (Math.ceil(widths[0]));

if (w > m_iTextWidth) {

m_iRealLine++;

m_String.addElement(string.substring(istart, i));

istart = i;

i--;

w = 0;

} else {

if (i == (string.length() - 1)) {

m_iRealLine++;

m_String.addElement(string.substring(istart,

string.length()));

}

}

}

}

canvas.setViewport(m_iTextWidth, m_iTextHeight);

for (int i = 0, j = 1; i < m_iRealLine; i++, j++) {

canvas.drawText((String) (m_String.elementAt(i)), x, y

+ m_iFontHeight * j, mPaint);

}

}

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

int measuredHeight = measureHeight(heightMeasureSpec);

int measuredWidth = measureWidth(widthMeasureSpec);

System.out.println("measuredHeight------->" + measuredHeight);

this.setMeasuredDimension(measuredWidth, measuredHeight);

this.setLayoutParams(new LinearLayout.LayoutParams(measuredWidth,

measuredHeight));

}

private int measureHeight(int measureSpec) {

int specMode = MeasureSpec.getMode(measureSpec);

int specSize = MeasureSpec.getSize(measureSpec);

// Default size if no limits are specified.

initHeight();

int result = m_iTextHeight;

Log.e("measureHeight---------------->", result + "");

return result;

}

private void initHeight() {

m_iTextHeight = 0;

FontMetrics fm = mPaint.getFontMetrics();

int m_iFontHeight = (int) Math.ceil(fm.descent - fm.top)

+ (int) LineSpace;

int line = 0;

int istart = 0;

int w = 0;

for (int i = 0; i < string.length(); i++) {

char ch = string.charAt(i);

float[] widths = new float[1];

String srt = String.valueOf(ch);

mPaint.getTextWidths(srt, widths);

if (ch == '\n') {

line++;

istart = i + 1;

w = 0;

} else {

w += (int) (Math.ceil(widths[0]));

if (w > m_iTextWidth) {

line++;

istart = i;

i--;

w = 0;

} else {

if (i == (string.length() - 1)) {

line++;

}

}

}

}

m_iTextHeight = (line) * m_iFontHeight;

Log.e("m_iTextHeight--------------------->", m_iTextHeight + "");

}

private int measureWidth(int measureSpec) {

int specMode = MeasureSpec.getMode(measureSpec);

int specSize = MeasureSpec.getSize(measureSpec);

// Default size if no limits are specified.

int result = 500;

if (specMode == MeasureSpec.AT_MOST) {

// Calculate the ideal size of your control

// within this maximum size.

// If your control fills the available space

// return the outer bound.

result = specSize;

} else if (specMode == MeasureSpec.EXACTLY) {

// If your control can fit within these bounds return that value.

result = specSize;

}

return result;

}

public void setText(String text) {

string = text;

initHeight();

invalidate();

requestLayout();

}

}

没有用到自定义属性,代码不太完美,以后改进

需要注意的是:

canvas.drawText(String str,int x,int y,Paint paint)中的x,y不能是左上角,而是一行的左下角,因为canvas绘制文本是根据基线为基准的

基线如图中baseLine

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: