(项目遇到的textview排版问题的亲测解决方案)

<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;
  }
}


 
 
 
 
亲测可用~!!

你可能感兴趣的:(textview)