为什么在Canvas上绘制的文本不能居中显示

前言

项目中碰到一个问题,需要在自定义View的中央绘制文字;算出了文字的高度,宽度,用自定义View的中心点坐标,减去1/2的高度(宽度)来作为起始坐标绘制文字,结果发现文字垂直方向不居中显示。

代码分析

出错的代码如下:

    //测量字符串长度
    float textLength = textPaint.measureText(text);
    //把文本画在圆心居中
    canvas.drawText(text, x - textLength/2, y+mTextSize/2, textPaint);

从效果上看,水平方向是居中的,但是垂直方向上的偏移量有问题,这里的偏移量是通过textSize获取的。

Android文本绘制原理介绍

为什么在Canvas上绘制的文本不能居中显示_第1张图片
Text绘制原理

android中的文字绘制是相对于图中的Baseline绘制的。bottom-top的高度是字体高度(textSize)

  • drawText函数说明


    为什么在Canvas上绘制的文本不能居中显示_第2张图片
    drawText函数说明

    这里的(x, y)的具体位置是Baseline上三个点中的一个(具体根据TextAlign的取值确定)


    为什么在Canvas上绘制的文本不能居中显示_第3张图片
    Baseline中的(x,y)

代码实现

所以这个问题的根源就是我们drawText中的x,y的含义弄错了;可用如下代码找到Baseline位置,并居中显示

Rect rect = new Rect(100,100,500,500);//画一个矩形
        Paint rectPaint = new Paint();
        rectPaint.setColor(Color.BLUE);
        rectPaint.setStyle(Paint.Style.FILL);
        canvas.drawRect(rect, rectPaint);

        Paint textPaint = new Paint();
        textPaint.setColor(Color.WHITE);
        textPaint.setTextSize(50);
        textPaint.setStyle(Paint.Style.FILL);
        //该方法即为设置基线上那个点到底是left,center,还是right  这里我设置为center
        textPaint.setTextAlign(Paint.Align.CENTER);

        Paint.FontMetrics fontMetrics = textPaint.getFontMetrics();
        float top = fontMetrics.top;//为基线到字体上边框的距离,即上图中的top
        float bottom = fontMetrics.bottom;//为基线到字体下边框的距离,即上图中的bottom

        int baseLineY = (int) (rect.centerY() - top/2 - bottom/2);//基线中间点的y轴计算公式

        canvas.drawText("你好世界",rect.centerX(),baseLineY,textPaint);
为什么在Canvas上绘制的文本不能居中显示_第4张图片
图示

baseLineY也可以这样计算:

int xPos = (canvas.getWidth() / 2);
 int yPos = (int) ((canvas.getHeight() / 2) - ((textPaint.descent() + textPaint.ascent()) / 2)) ; 
 //((textPaint.descent() + textPaint.ascent()) / 2) is the distance from the baseline to the center.

你可能感兴趣的:(为什么在Canvas上绘制的文本不能居中显示)