Centering Single-Line text in a canvas

本文介绍如何在Android中实现单行文本在Canvas上水平垂直居中显示的方法。通过使用TextPaint对象的ascent()和descent()方法测量文本高度,并通过简单的数学计算调整基线位置,使得文本能够精确地居中显示。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >



The problem is that while you can easily set a horizontal alignment for your TextPaint (via Paint.Align),the 

vertical alignment is tricky.  That's because Canvas.drawText() starts drawing at the baseline of your set Y-

coordinate, instead of the center.

If you only knew the height of the text, then you could center it yourself - but getting the height is tricky!  

TextPaint.getTextBounds() doesn't work quite right because it gives you the minimal bounding rectangle,

 not the height that the TextPaint draws.  For example, if your text has no ascenders/descenders, then the

measured height is smaller than it will draw (since it will still account for the possibility of them).

The way I've found to get the height of the TextPaint is to use ascent() and descent().  These measure the

size above/below the text's baseline.  Combined, they add up to the total height of the drawn text.  You can

 then use some math to center the draw on the baseline - here's a version of onDraw() that does it correctly*:

or u can use Paint.FontMetricsInt fontMetrics = mTextPaint.getFontMetricsInt(); to get the descent and ascent of textPaint

protected void onDraw(Canvas canvas) {
  super.onDraw(canvas);

  Paint paint = new Paint();
  paint.setColor(Color.BLACK);

  TextPaint textPaint = new TextPaint();
  textPaint.setColor(Color.WHITE);
  textPaint.setTextAlign(Paint.Align.CENTER);
  float textHeight = textPaint.descent() - textPaint.ascent();
  float textOffset = (textHeight / 2) - textPaint.descent();
or 
  Paint.FontMetricsInt fontMetrics = textPaint.getFontMetricsInt();
  float textHeight = fontMetrics.decent-fontMetrics.ascent;
  float textOffset = (textHeight/2)-fontMetrics.dscent;
  RectF bounds = new RectF(0, 0, getWidth(), getHeight());
  canvas.drawOval(bounds, paint);
  canvas.drawText("42", bounds.centerX(), bounds.centerY() + textOffset, textPaint);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值