android text自动换行,【Android】TextView自动换行文字排版参差不齐的原因
参考网上文章:publicclassCYTextViewextendsTextView{publicstaticintm_iTextHeight;//文本的高度publicstaticintm_iTextWidth;//文本的宽度privatePaintmPaint=null;privateStringstring="";privatefloatLi...
参考网上文章:
public class CYTextView extends TextView {
public static int m_iTextHeight; // 文本的高度
public static int m_iTextWidth;// 文本的宽度
private Paint mPaint = null;
private String string = "";
private float LineSpace = 0;// 行间距
private Context context;
public CYTextView(Context context, AttributeSet set) {
super(context, set);
this.context = context;
TypedArray typedArray = context.obtainStyledAttributes(set, R.styleable.CYTextView);
float textsize = typedArray.getDimension(R.styleable.CYTextView_mytextSize, 20);
int textcolor = typedArray.getColor(R.styleable.CYTextView_mytextColor, -1442840576);
float linespace = typedArray.getDimension(R.styleable.CYTextView_lineSpacingExtra, -12);
int typeface = typedArray.getColor(R.styleable.CYTextView_typeface, 0);
linespace = DensityUtil.dip2px(context, -5);
typedArray.recycle();
// 设置 CY TextView的宽度和行间距www.linuxidc.com
LineSpace = linespace;
// 构建paint对象
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setColor(textcolor);
mPaint.setTextSize(textsize);
switch (typeface) {
case 0:
mPaint.setTypeface(Typeface.DEFAULT);
break;
case 1:
mPaint.setTypeface(Typeface.SANS_SERIF);
break;
case 2:
mPaint.setTypeface(Typeface.SERIF);
break;
case 3:
mPaint.setTypeface(Typeface.MONOSPACE);
break;
default:
mPaint.setTypeface(Typeface.DEFAULT);
break;
}
}
@Override
public void setMaxLines(int maxlines) {
super.setMaxLines(maxlines);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (m_iTextWidth <= 0) {
return;
}
char ch;
int w = 0;
int istart = 0;
int m_iFontHeight;
int m_iRealLine = 0;
int x = DensityUtil.dip2px(context, 20); //60; //距左的距离
int y = 10;
Vector m_String = new Vector();
FontMetrics fm = mPaint.getFontMetrics();
m_iFontHeight = (int) Math.ceil(fm.descent - fm.top) + (int) LineSpace;// 计算字体高度(字体高度+行间距)
y = (int) Math.ceil(fm.descent - fm.top);
for (int i = 0; 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()));
}
}
}
}
/**这里是需求要求2行*/
if (m_iRealLine > 2){
m_iRealLine = 2;
}
m_iTextHeight = m_iRealLine * m_iFontHeight + 2;
// canvas.setViewport(m_iTextWidth, m_iTextWidth);
for (int i = 0, j = 0; i
canvas.drawText((String) (m_String.elementAt(i)), x, y + m_iFontHeight * j, mPaint);
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int measuredWidth = measureWidth(widthMeasureSpec);
m_iTextWidth = measuredWidth;
/**这里也是需求要求*/
m_iTextWidth = m_iTextWidth - DensityUtil.dip2px(context, 26);
int measuredHeight = measureHeight(heightMeasureSpec);
this.setMeasuredDimension(measuredWidth, measuredHeight);
// super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
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;
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;
}
private void initHeight() {
// 设置 CY TextView的初始高度为0
m_iTextHeight = 0;
// 大概计算 CY TextView所需高度
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
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++;
}
}
}
}
/**这里是需求,要求两行*/
if (line > 2){
line = 2;
}
m_iTextHeight = (line) * m_iFontHeight + 2;
}
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) {// 注:此函数目前只有在UI线程中调用才可以把文本画出来,在其它线程中
// //无法画文本,找了好久找不到原因,求高手解答)
string = text;
requestLayout();
invalidate();
}
}
xmlns:cy="http://schemas.android.com/apk/res-auto"
android:id="@+id/tv_product_title"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:maxLines="2"
android:paddingLeft="26dp"
android:paddingRight="10dp"
android:layout_marginBottom="5dp"
android:text=""
cy:mytextSize="16sp" />
这里是通过文本的宽高调用onDraw方法来绘制的。但是像android:paddingLeft, android:maxLines等这些属性配置是不管用的,其实用起来还是不方便
public class DensityUtil {
/**
* dip转换成px
*/
public static int dip2px(Context context, float dpValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}
/**
* px转换成dip
*/
public static int px2dip(Context context, float pxValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (pxValue / scale + 0.5f);
}
}
更多推荐
所有评论(0)