首页 > 系统 > Android > 正文

Android实现TextView两端对齐的方法

2020-04-11 11:02:28
字体:
来源:转载
供稿:网友

Android中的TextView控件默认是做不到两端对齐的,都是左对齐。可能的原因是安卓默认数字、字母不能为第一行以后每行的开头字符,因为数字、字母为半角字符,还有就是文字中的英文字符占用1个字节,而一个汉字占用两个字节。下面我就介绍下实现两端对齐的原理:

  • 1、测量一个中文汉字所占用的宽度
  • 2、根据TextView的宽度和一个汉字所占用的宽度以及字符之间的间隔计算出总行数。
  • 3、根据padding和margin以及行高计算出TextView的总高度。
  • 4、绘制每一行的每一个字符

效果如下:

具体代码如下:

package com.wedroid.framework.module.ui;import android.content.Context;import android.graphics.Canvas;import android.graphics.Paint;import android.text.TextPaint;import android.text.TextUtils;import android.util.AttributeSet;import android.view.ViewGroup.MarginLayoutParams;import android.view.ViewTreeObserver.OnPreDrawListener;import android.widget.TextView;public class WeDroidAlignTextView extends TextView {  private boolean first = true;  public WeDroidAlignTextView(Context context, AttributeSet attrs, int defStyle) {    super(context, attrs, defStyle);    getViewTreeObserver().addOnPreDrawListener(new OnPreDrawListener() {      @Override      public boolean onPreDraw() {        initTextInfo();        return true;      }    });  }  public WeDroidAlignTextView(Context context, AttributeSet attrs) {    this(context, attrs, 0);  }  public WeDroidAlignTextView(Context context) {    this(context, null, 0);  }  private float textSize;  private float textLineHeight;  private int top;  private int y;  private int lines;  private int bottom;  private int right;  private int left;  private int lineDrawWords;  private char[] textCharArray;  private float singleWordWidth;  private float lineSpacingExtra;  public void initTextInfo() {    textSize = getTextSize();    textLineHeight = getLineHeight();    left = 0;    right = getRight();    y = getTop();    // 要画的宽度    int drawTotalWidth = right - left;    String text = getText().toString();    if (!TextUtils.isEmpty(text) && first) {      textCharArray = text.toCharArray();      TextPaint mTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);      mTextPaint.density = getResources().getDisplayMetrics().density;      mTextPaint.setTextSize(textSize);      // 一个单词的的宽度      singleWordWidth = mTextPaint.measureText("一") + lineSpacingExtra;      // 一行可以放多少个字符      lineDrawWords = (int) (drawTotalWidth / singleWordWidth);      int length = textCharArray.length;      lines = length / lineDrawWords;      if ((length % lineDrawWords) > 0) {        lines = lines + 1;      }      first = false;      MarginLayoutParams layoutParams = (MarginLayoutParams) getLayoutParams();      int totalHeight = (int) (lines*textLineHeight+textLineHeight*2 + getPaddingBottom()+getPaddingTop()+layoutParams.bottomMargin+layoutParams.topMargin);      setHeight(totalHeight);    }  }  @Override  protected void onDraw(Canvas canvas) {    bottom = getBottom();    int drawTotalLine = lines;    if(maxLine!=0&&drawTotalLine>maxLine){      drawTotalLine = maxLine;    }    for (int i = 0; i < drawTotalLine; i++) {      try {        int length = textCharArray.length;        int mLeft = left;        // 第i+1行开始的字符index        int startIndex = (i * 1) * lineDrawWords;        // 第i+1行结束的字符index        int endTextIndex = startIndex + lineDrawWords;        if (endTextIndex > length) {          endTextIndex = length;          y += textLineHeight;        } else {          y += textLineHeight;        }        for (; startIndex < endTextIndex; startIndex++) {          char c = textCharArray[startIndex];//         if (c == ' ') {//           c = '/u3000';//         } else if (c < '/177') {//           c = (char) (c + 65248);//         }          canvas.drawText(String.valueOf(c), mLeft, y, getPaint());          mLeft += singleWordWidth;        }      } catch (Exception e) {        e.printStackTrace();      }    }  }  int maxLine;  public void setMaxLines(int max){    this.maxLine = max;  }  public void setLineSpacingExtra(int lineSpacingExtra){    this.lineSpacingExtra = lineSpacingExtra;  }   /**    * 判断是否为中文    * @return    */   public static boolean containChinese(String string){     boolean flag = false;     for (int i = 0; i < string.length(); i++) {       char c = string.charAt(i);       if ((c >= 0x4e00) && (c <= 0x9FA5)) {         flag = true;       }     }     return flag;   }  public static String ToDBC(String input) {    // 导致TextView异常换行的原因:安卓默认数字、字母不能为第一行以后每行的开头字符,因为数字、字母为半角字符    // 所以我们只需要将半角字符转换为全角字符即可    char c[] = input.toCharArray();    for (int i = 0; i < c.length; i++) {      if (c[i] == ' ') {        c[i] = '/u3000';      } else if (c[i] < '/177') {        c[i] = (char) (c[i] + 65248);      }    }    return new String(c);  }}

希望本文所述对大家学习Android程序设计有所帮助。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表