文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Android实现TextView两端对齐的方法

2022-06-06 09:14

关注

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;
  }
    
  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程序设计有所帮助。

您可能感兴趣的文章:Android TextView两端对齐解决办法Android TextView对齐的两种方法


阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-移动开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯