Android UI 之居中绘制文本内容的正确方法——实现自定义一个TextView
我们在自定义一个控件的时候,有时候会需要自己来绘制一些文本内容,这样就自然而然遇到确定文本的方位的问题,比如文本需要水平居中,垂直居中,居左,居右,左上。。。等等很多情况。其中最常见的就是文本位于控件的正中央了。
既然是文本居中,那就要让文本水平居中,并且同时垂直居中,我们分开来做。
水平居中的思路很简单,一种是得到控件的宽度A,使得文本的中心位置x坐标=A/2就可以了。还有一种思路是我们得到控件的宽度A,然后测量出要绘制的文本的宽度B,然后使得文本的左端x坐标=(A-B)/2。
相对复杂一点的实现文本垂直居中,我们需要用到FontMetrics,这里涉及到几个概念,分别是文本的top,bottom,ascent,descent,baseline。看下面的图:

我们在画布中绘制文本的时候,会调用Canvas.drawText(String text, float x, float y, Paint paint)这个方法,其中y的坐标就是上图中baseline的y坐标,所以,如果我们只是简单地把drawText方法中的y设置为控件高度的1/2是不准确的,如果这样做的话会发现文本整体是位于画布的上半部分的,因为baseline下面的文本部分是很小的。
正确的做法是通过一些合理的换算使得文本的y坐标(baseline的y坐标)位于控件的下半部分区域。下面是我自己通过计算和测试得到的准确换算关系:
然后是使用(fm.descent - fm.ascent) / 2:
左边绿色的是系统的TextView文字居中效果,右边是我们自定义控件的文字居中效果,可以看出使用(fm.bottom - fm.top) / 2与TextView的效果是一样的,当然,我们不必一定要与TextView的效果相同,所以使用(fm.descent - fm.ascent) / 2也是可以的。
然后我们扩展一下,自定义一个可以控制内部文本绘制方位的TextView。
先来看一下效果图:
项目代码:
MyTextView.java
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity" > <LinearLayout android:id="@+id/container" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"/></ScrollView>另外,还用到了两个工具类,代码可以参考这篇文章http://blog.csdn.net/carrey1989/article/details/10360613在进行垂直偏上和垂直偏下的设置时,关键是设置baseline的y坐标分别等于-fm.ascent和viewHeight - fm.bottom,意思就是可以让文字刚好不超过控件的边缘。
整体思路就是这样,如需转载,请注明转载地址http://blog.csdn.net/carrey1989/article/details/10399727
- 1楼suannai03144天前 10:53
- 您的文章已被推荐到博客首页和个人页侧边栏推荐文章,感谢您的分享。
- Re: u011880994前天 06:33
- 回复suannai0314



