1. 落笔缘由

为了实现(如下图1)文字两端对齐的效果。

android设置与左侧布局对齐并垂直居中_半角


在这之前有想过使用半角空格转换成全角空格来实现这个效果,但是效果不是很好,而且比较麻烦,只要有一行文字的字数改变了,都有可能要从新计算文字直接要填充多少个空格才能实现文字两端对齐。

然后在网上找了找,希望能找到自定义组件,但是大多是针对一篇文章实现文章两端离屏幕两端间距相等的效果,但我希望的是除了两端对齐之外,还希望每个字的间距相等,如下图二:

android设置与左侧布局对齐并垂直居中_android_02

So,还是自己来自定义这个控件吧,实现这个效果主要解决2个问题:
(1)canvas中drawText实现文字垂直方向居中
(2)计算出文字之间的距离

2. 实现

(1)首先要解决drawText文字垂直方向居中问题,这个在[android][canvas中drawText绘制文字垂直方向居中]一文中已经找到了解决方法。
(2)计算出文字之间的距离

if (this.text!=null)
{
   textCount = text.length();
   if (textCount<=0)
   {
      return;
   }
   //文本总宽度
   float textWidth = tPaint.measureText(String.valueOf(text));
   Paint.FontMetrics metrics = tPaint.getFontMetrics();
   textH = (mHeight-(metrics.descent-metrics.ascent))/2-metrics.ascent;
   //当文本总宽度大于控件的宽度,重新定义文字的尺寸
   if (textWidth>mWidth)
   {
      textSize = mWidth/textCount;
      tPaint.setTextSize(textSize);
      textWidth = mWidth;
   }
   //每个字的宽度
   eachwidth = textWidth/textCount;
   //偏移值,(宽度-字数的总宽度)/(字数-1)
   offset = (mWidth-textWidth)/(textCount-1);
}

计算出间距之后,就要确定每个文字要绘制的坐标,第一个和最后一个字的坐标确定了的,每个字垂直方向的坐标是baseline的纵坐标,这样才能在垂直方向居中,而水平方向的每个字的横坐标(除了第一和最后一个字外),应该是前一个字符的宽+偏移值。如图三

android设置与左侧布局对齐并垂直居中_全角_03

代码实现如下:

if (this.text!=null)
{
   for (int i = 0; i < textCount; i++)
   {
      if (i==0)//第一个字的位置
      {
         canvas.drawText(String.valueOf(text.charAt(i)), offset*(i), textH, tPaint);
      }else if (i==textCount-1)//最后个字的位置
      {
         canvas.drawText(String.valueOf(text.charAt(i)), mWidth-eachwidth, textH, tPaint);
      }else
      {
         canvas.drawText(String.valueOf(text.charAt(i)), (offset+eachwidth)*i, textH, tPaint);
      }

   }
}

现在,就能实现两端对齐,每个字的间距相等的效果,如下图四:

android设置与左侧布局对齐并垂直居中_半角_04


也许你也看到了,最后一行的字号大小明显和上面的不一样,这是因为我在代码中做了处理,如果字号过大,重新计算字号大小,保证能文字能完全显示。这里只是为了方便我根据显示的效果来觉得使用多大的字号。

3. 总结

(1) 获取文本宽度的方法

tPaint.measureText(String text)

在网上找了还有其他方法,但是个人比较喜欢这个方式。
(2)半角与全角
之前是希望通过使用空格来控制每个文字直接的距离,但是发现表单文字两端不对齐,所以就不整了。下面是全角和半角的概念,网上搜索都能找到,这里只是为了记录一下当时的思路。
1)全角:是一种电脑字符,是指一个全角字符占用两个标准字符(或两个半角字符)的位置。全角占两个字节。
   汉字字符和规定了全角的英文字符及国标GB2312-80中的图形符号和特殊字符都是全角字符。在全角中,字母和数字等与汉字一样占据着等宽的位置。
2)半角:是指一个字符占用一个标准的字符位置。半角占一个字节。
半角就是 ASCII 方式的字符,在没有汉字输入法起作用的时候,输入的字母、数字和字符都是半角的。
  每个半角字符只占用一字节的空间(一字节有8位,共256个编码空间)。汉语、日语、及朝鲜文等象形字语言的字库量远大于256个编码空间,所以改用两个字节来储存。同时,由于中日韩等象形文字的书写习惯,如果统一使用全角字符的话,排列起来也显得整齐。

android设置与左侧布局对齐并垂直居中_半角_05

如果你还是希望通过修改字符串来实现,可以按照如下的方法:
在String.xml下定义你的字符串

<string name="namestring">用 户 名:</string>

在布局文件的xml中直接设置

<TextView  
    android:id="@+id/tv_receive_tag"  
    android:layout_width="wrap_content"  
    android:layout_height="wrap_content"  
    android:layout_alignParentLeft="true"  
    android:textColor="@color/gray_3"  
    android:textSize="14sp"  
    android:text="@string/namestring" />

在代码中设置

mTextView.setText(mContext.getString(R.string.namestring));

还有另一个方法也可以实现靠只改变字符串即可

android设置与左侧布局对齐并垂直居中_半角_06

看到上面的介绍,我们可以直接如下操作:

mTextView.setText(Html.fromHtml("目 的 地"));

4. 源码地址

https://github.com/lgygg/TestLJustifyTextView

5. 参考文章

http://www.xuexila.com/zhishi/jichu/533699.html