解決android系統TextView自動換行不美觀問題

來源:互聯網
上載者:User

轉寄至: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

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.