如何在Canvas的Bitmap(Drawable XML)内部显示文本?
解决Canvas中文字显示在Bitmap圆形内部的问题
嘿,我明白你的困扰了!你现在是先把圆形Drawable转成Bitmap,然后用canvas.drawBitmap()画出来,再用drawText()加文字,但文字跑到Bitmap上面去了对吧?这是因为你没把文字的绘制坐标和Bitmap的位置、尺寸对齐,而且文字的基线绘制特性也会影响位置。咱们一步步来搞定它:
方法一:调整文字坐标,让它居中在Bitmap内部
1. 明确Bitmap的位置和尺寸
先把你绘制Bitmap时的坐标和它的宽高存下来,方便后续计算:
// 假设你绘制Bitmap的起始坐标 float bitmapLeft = 150f; float bitmapTop = 150f; // 获取Bitmap的宽高 int bitmapWidth = yourCircleBitmap.getWidth(); int bitmapHeight = yourCircleBitmap.getHeight();
2. 配置文字Paint并计算文字尺寸
设置文字的样式,然后获取文字的边界,这样才能准确计算居中位置:
Paint textPaint = new Paint(); textPaint.setTextSize(28f); // 根据你的圆形大小调整文字尺寸 textPaint.setColor(Color.WHITE); // 选个和圆形对比明显的颜色 textPaint.setTextAlign(Paint.Align.CENTER); // 设置文字居中对齐,简化X坐标计算 textPaint.setAntiAlias(true); // 让文字更平滑 String targetText = "5"; // 你要显示的文字 Rect textBounds = new Rect(); textPaint.getTextBounds(targetText, 0, targetText.length(), textBounds); int textHeight = textBounds.height();
3. 计算文字的绘制坐标并绘制
关键是让文字在圆形Bitmap的中心:
- X坐标:Bitmap的中心X,也就是
bitmapLeft + bitmapWidth / 2f(因为我们设置了Align.CENTER,文字会以这个点为中心左右对齐) - Y坐标:Bitmap的中心Y加上文字高度的一半,因为文字的基线默认在下方,这样调整后文字能垂直居中
然后记住先画Bitmap,再画文字,这样文字才会覆盖在Bitmap内部:
// 先绘制圆形Bitmap canvas.drawBitmap(yourCircleBitmap, bitmapLeft, bitmapTop, null); // 再绘制文字到Bitmap中心 float textX = bitmapLeft + bitmapWidth / 2f; float textY = bitmapTop + bitmapHeight / 2f + textHeight / 2f; canvas.drawText(targetText, textX, textY, textPaint);
方法二:自定义Drawable,让圆形和文字成为一体
如果你的圆形是固定样式的,直接自定义一个Drawable,把圆形和文字一起画,这样就不用分开处理Bitmap和文字了,更省心:
public class TextCircleDrawable extends Drawable { private final Paint circlePaint; private final Paint textPaint; private final String displayText; public TextCircleDrawable(String text) { this.displayText = text; // 初始化圆形画笔 circlePaint = new Paint(Paint.ANTI_ALIAS_FLAG); circlePaint.setColor(Color.parseColor("#2196F3")); // 圆形颜色 // 初始化文字画笔 textPaint = new Paint(Paint.ANTI_ALIAS_FLAG); textPaint.setColor(Color.WHITE); textPaint.setTextSize(32f); textPaint.setTextAlign(Paint.Align.CENTER); } @Override public void draw(@NonNull Canvas canvas) { Rect drawBounds = getBounds(); // 绘制圆形(以Drawable的边界为基准画正圆) float circleRadius = Math.min(drawBounds.width(), drawBounds.height()) / 2f; canvas.drawCircle(drawBounds.centerX(), drawBounds.centerY(), circleRadius, circlePaint); // 绘制文字到圆形中心 Rect textBounds = new Rect(); textPaint.getTextBounds(displayText, 0, displayText.length(), textBounds); float textY = drawBounds.centerY() + textBounds.height() / 2f; canvas.drawText(displayText, drawBounds.centerX(), textY, textPaint); } @Override public void setAlpha(int alpha) { circlePaint.setAlpha(alpha); textPaint.setAlpha(alpha); } @Override public void setColorFilter(@Nullable ColorFilter colorFilter) { circlePaint.setColorFilter(colorFilter); textPaint.setColorFilter(colorFilter); } @Override public int getOpacity() { return PixelFormat.TRANSLUCENT; } }
使用的时候,你可以直接把这个Drawable转成Bitmap,或者直接调用它的draw()方法绘制到Canvas上,这样圆形和文字就是一个整体,不会出现位置偏移的问题。
内容的提问来源于stack exchange,提问作者Soumya Priya Nayak
相关产品推荐
相关产品推荐

