一. 前言
画笔的设置会影响到文字的绘制。所以,我们需要先了解自定义View-Paint。
绘制文本有三类方法:
其中drawText()最常用,drawPosText ()是根据一个个坐标点指定文字位置,drawTextOnPath ()是根据路径绘制。
1 2 3 4 5 6 7 8 9 10 11 12 13
| public void drawText (String text, float x, float y, Paint paint) public void drawText (String text, int start, int end, float x, float y, Paint paint) public void drawText (CharSequence text, int start, int end, float x, float y, Paint paint) public void drawText (char[] text, int index, int count, float x, float y, Paint paint)
public void drawPosText (String text, float[] pos, Paint paint) public void drawPosText (char[] text, int index, int count, float[] pos, Paint paint)
public void drawTextOnPath (String text, Path path, float hOffset, float vOffset, Paint paint) public void drawTextOnPath (char[] text, int index, int count, Path path, float hOffset, float vOffset, Paint paint)
|
二. drawText
1
| public void drawText (String text, float x, float y, Paint paint)
|
很明显,这里的 x 和 y 是用来确定文本的绘制位置的。但是,这个点是绘制文本的那里,我们还是不清楚。
1. 测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| Paint paint=new Paint(); paint.setStyle(Paint.Style.FILL); paint.setStrokeWidth(12); paint.setTextSize(100);
String text="测试:my text"; canvas.drawText(text, 200, 400, paint);
paint.setStrokeWidth(4); paint.setColor(Color.RED); canvas.drawLine(0, 400, 2000, 400, paint); paint.setColor(Color.BLUE); canvas.drawLine(200, 0, 200, 2000, paint);
|

x的值默认是文字的左边界,通过setTextAlign()指定,默认为left。

setTextAlign()指定为center,此时x的值是文字的中心位置。

setTextAlign()指定为right,此时x的值是文字的右边界。
这里,我们就很清楚的知道了Paint的setTextAlign方法的作用以及drawText方法中x值的作用。
drawText方法中y值我们猜测应该是文字的下边界,但是通过测试发现,y值比文字的下边界高。
2. 文字的基线

透过这张图的字符y以及对比上面图中的字母y我们可以发现,y的值是Baseline,也就是文字的基线。
那么,这些值如何获取呢?
1 2 3 4 5
| Paint.FontMetrics fontMetrics=paint.getFontMetrics(); fontMetrics.top fontMetrics.ascent fontMetrics.descent fontMetrics.bottom
|
记得要在设置完Paint的文字大小,宽度之类属性后再获取FontMetrics,baseline对应对应值为0,在它下面的descent和bottom值为正,top和ascent为负。那文字的高度为bottom - top
3. 文字居中方案
① y = 矩形中心y值 + 矩形中心与基线的距离
② 矩形中心与基线的距离 = 文字高度的一半 - 基线到文字底部的距离(也就是bottom)
1
| (fontMetrics.bottom - fontMetrics.top)/2 - fontMetrics.bottom
|
三. demo
1. MyTextView类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| public class MyTextView extends View { private Paint paint;
public MyTextView(Context context) { super(context);
init(); }
public MyTextView(Context context, @Nullable AttributeSet attrs) { super(context, attrs);
init(); }
private void init(){ paint = new Paint(); paint.setColor(Color.WHITE); paint.setTextSize(40); }
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas);
String message = "Hello,you!";
float textWidth = paint.measureText(message); float textHeight = paint.getFontMetrics().bottom-paint.getFontMetrics().top;
float distance = textHeight / 2 - paint.getFontMetrics().bottom;
float x = (getWidth() - textWidth) / 2;
float y = (getHeight() - textHeight) / 2 + textHeight / 2 + distance;
canvas.drawText( "Hello,you!", x, y, paint ); } }
|
2. 布局文件中使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity">
<swu.xl.drawtext.MyTextView android:layout_width="300dp" android:layout_height="100dp" android:layout_centerInParent="true" android:background="@color/colorAccent" />
</RelativeLayout>
|
3. 运行效果
参考文章
Android Canvas的drawText()和文字居中方案
android高级自定义View之Paint高级使用(文字绘制)