解决Canvas绘制数字网格时文本错位、排版不规则问题
Let's break down why your numbers aren't aligning properly in the grid—this is a super common gotcha with Canvas.drawText()!
The Root Cause: Baseline vs. Vertical Center
Your horizontal calculation is spot-on thanks to textAlign = Paint.Align.CENTER, but the vertical positioning is tripping you up. Here's the key: the y parameter in drawText() doesn't represent the vertical center of the text—it represents the text's baseline.
The baseline is the invisible line that most characters sit on (think the bottom of lowercase letters like "a" or "z"). Numbers (like "0" or "9") have their vertical center offset from this baseline, so when you set textY to the tile's center, the actual text ends up shifted up or down instead of being centered.
The Fix: Adjust for Baseline Offset
You need to calculate the vertical offset needed to shift the baseline so that the text's center lines up with your textY value. Here's how to do it:
Calculate the offset using your Paint's metrics
ThePaintclass gives you access to text metrics that tell you the distance from the baseline to the top (ascent) and bottom (descent) of the text. We can use these values to find how much we need to adjust the baseline.Modify your drawText call
Update your code to include this offset:
val textX = x * TILE_SIZE + TILE_SIZE / 2f val textY = y * TILE_SIZE + TILE_SIZE / 2f // Calculate the vertical offset to center the text relative to baseline val verticalOffset = (textPaint.ascent() + textPaint.descent()) / 2f // Draw the text with adjusted y-coordinate canvas.drawText(number.toString(), textX, textY - verticalOffset, textPaint)
Why This Works
ascent()returns a negative value (it's measured upward from the baseline)descent()returns a positive value (measured downward from the baseline)- Adding them together gives the total height of the text relative to the baseline, and dividing by 2 gives the offset of the text's center from the baseline. Subtracting this offset from
textYshifts the baseline so the text's vertical center lines up with your tile's center.
Quick Check: Verify Units
Make sure TILE_SIZE is in the same unit as your textSize (both should be pixels). Since you're setting textSize = TILE_SIZE * 0.1f, this is already handled—just a quick sanity check to rule out unit mismatches.
Give this a try, and your numbers should snap perfectly into the center of each grid tile!
内容的提问来源于stack exchange,提问作者Martin Rončka

