<pre name="code" class="java">package com.lencee.coral.ui.widget;
import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.Canvas;
import android.os.Build;
import android.text.TextPaint;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.widget.TextView;
/**
* Created by Rob X on 14/11/7.
*/
public class FixedWrapTextView extends TextView {
private static final String TAG = "FixedWrapTextView";
private TextPaint mTextPaint;
private String mContent;
public FixedWrapTextView(Context context) {
this(context, null);
}
public FixedWrapTextView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public FixedWrapTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public FixedWrapTextView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
/**
* 这里使用它代替setText方法
*/
public void setContent(String content) {
if (!TextUtils.isEmpty(content)) {
this.mContent = content;
invalidate(); //传入显示字符串,请求界面刷新
}
}
public String getContent() {
return mContent;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mTextPaint = getPaint(); //获取画笔
String[] texts = autoSplit(mTextPaint, mContent, getWidth()); //将文本存进相应的行
float lineHeight = getLineHeight(); //获取行高
float x = 0;
float y = lineHeight;
for (String text : texts) {
canvas.drawText(text, x, y, mTextPaint);
y += lineHeight; //一行一行的绘制
}
/*
xml里的宽度必须指定,不能为wrap_content
xml里的高度由于设置的为wrap_content,所以这里需要对高度进行计算,而按照正常逻辑计算出来的高度会短一点(原因待深究)
因此这里是直接写死添加了半个行高,然后对多种类型的机型进行测试,效果很好
*/
setHeight((int) (lineHeight * (texts.length + .5)));
}
/**
* 自动分割文本
*
* @param content 需要分割的文本
* @param paint 画笔,用来根据字体测量文本的宽度
* @param viewWidth 指定的宽度
* @return 一个字符串数组,保存每行的文本
*/
private String[] autoSplit(TextPaint paint, String content, int viewWidth) {
float textWidth = paint.measureText(content); //返回传入文本的累加宽度
if (textWidth <= viewWidth) {
return new String[] { content }; //说明只有一行,直接返回
}
int length = content.length();
int lines = (int) Math.ceil(textWidth / viewWidth); //获取到需要显示的行数
String[] texts = new String[lines];
StringBuilder builder = new StringBuilder();
float width = 0;
int index = 0;
for (int i = 0; i < length; i++) { //将字符串进行拆分
char word = content.charAt(i); //一个字符一个字符的获取到
float temp = mTextPaint.measureText(String.valueOf(word)); //再获取到其宽度
width += temp; //累加
if (width > viewWidth) {//如果当前累加的宽度大于指定宽度,说明需要换行了
texts[index] = builder.toString(); //存储当前累加的字符串
builder.setLength(0);
index++; //索引跳下一行
width = temp;
}
builder.append(word);
if (i == length - 1) { //说明已拆分到末尾
texts[index] = builder.toString();
}
}
builder.setLength(0);
return texts;
}
}
亲测可用~!!