我试图使用下面的代码显示一个文本。 问题是文本没有水平居中。 当我为drawText设置坐标时,它将文本的底部设置在这个位置。我想要的文本被绘制,使文本也是水平居中。

这是一张进一步展示我的问题的图片:

@Override
protected void onDraw(Canvas canvas) {
    // TODO Auto-generated method stub
    super.onDraw(canvas);
    //canvas.drawRGB(2, 2, 200);
    Paint textPaint = new Paint();
    textPaint.setARGB(200, 254, 0, 0);
    textPaint.setTextAlign(Align.CENTER);
    textPaint.setTypeface(font);
    textPaint.setTextSize(300);
    canvas.drawText("Hello", canvas.getWidth()/2, canvas.getHeight()/2  , textPaint);
}

当前回答

您的代码正在绘制文本基线的中心,在视图的中心。为了让文本在某个点(x, y)居中,你需要计算文本的中心,并把它放在这个点上。

这个方法将在点x, y居中绘制文本。如果你将它传递到视图的中心,它将以居中绘制文本。

private void drawTextCentered(String text, int x, int y, Paint paint, Canvas canvas) {
    int xPos = x - (int)(paint.measureText(text)/2);
    int yPos = (int) (y - ((textPaint.descent() + textPaint.ascent()) / 2)) ;

    canvas.drawText(text, xPos, yPos, textPaint);
}

其他回答

如果我们使用静态布局

mStaticLayout = new StaticLayout(mText, mTextPaint, mTextWidth,
                Layout.Alignment.ALIGN_CENTER, 1.0f, 0, true);

Layout.Alignment。ALIGN_CENTER这将完成任务。静态布局也有很多其他的优点。

参考:Android文档

在我的例子中,我不需要把文本放在画布的中间,而是放在一个旋转的轮子上。尽管我必须使用以下代码才能成功:

fun getTextRect(textSize: Float, textPaint: TextPaint, string: String) : PointF {
    val rect = RectF(left, top, right, bottom)
    val rectHeight = Rect()
    val cx = rect.centerX()
    val cy = rect.centerY()

    textPaint.getTextBounds(string, 0, string.length, rectHeight)
    val y = cy + rectHeight.height()/2
    val x = cx - textPaint.measureText(string)/2

    return PointF(x, y)
}

然后我从View类调用这个方法:

private fun drawText(canvas: Canvas, paint: TextPaint, text: String, string: String) {
    val pointF = getTextRect(paint.textSize, textPaint, string)
    canvas.drawText(text, pointF!!.x, pointF.y, paint)
}

试试下面的方法:

 Paint textPaint = new Paint();
 textPaint.setTextAlign(Paint.Align.CENTER);

 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.drawText("Hello", xPos, yPos, textPaint);

适用于我使用: textPaint。textAlign = Paint.Align.CENTER使用textPaint.getTextBounds

private fun drawNumber(i: Int, canvas: Canvas, translate: Float) {
            val text = "$i"
            textPaint.textAlign = Paint.Align.CENTER
            textPaint.getTextBounds(text, 0, text.length, textBound)

            canvas.drawText(
                    "$i",
                    translate + circleRadius,
                    (height / 2 + textBound.height() / 2).toFloat(),
                    textPaint
            )
        }

结果是:

在你的油漆属性中使用这个:

 textPaint.setTextAlign(Paint.Align.CENTER);