我必须使用 Canvas 创建一个圆弧并在圆弧的起始位置添加文本,但它看起来不正确。请看图片,我的文字被剪掉了顶部位置,我的文字显示为线性而不是曲线。
我的代码
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mRect == null) {
centerX = getMeasuredWidth() / 2;
centerY = getMeasuredHeight() / 2;
radius = Math.min(centerX, centerY);
int startTop = STROKE_WIDTH / 2;
mRect = new RectF(STROKE_WIDTH / 2, STROKE_WIDTH / 2, (2 * radius - startTop), (2 * radius - startTop));
canvas.drawArc(mRect, 270, 270, false, mDegreesPaint);
Paint paint = new Paint();
paint.setColor(Color.TRANSPARENT);
paint.setAntiAlias(true);
paint.setStyle(Paint.Style.FILL_AND_STROKE);
paint.setTextAlign(Paint.Align.LEFT);
paint.setLinearText(true);
canvas.drawPaint(paint);
paint.setColor(getResources().getColor(R.color.colorPrimaryDark));
paint.setTextSize(30);
//float radius = 300;
float x = (float)(radius * Math.cos(mRect.width() * Math.PI)) + getWidth()/2 - 10;
float y = (float)(radius * Math.sin(mRect.height() * Math.PI )) + getHeight()/2 - 20;
Path addArc = new Path();
addArc.arcTo(mRect, 250, 270);
canvas.drawTextOnPath("text",addArc, 0, 0 , paint);
}
}
最佳答案
如果 View 被重绘,if (mRect == null)
行会让你陷入困境。它会变成空白。您应该在其声明处实例化矩形并在 onDraw() 中修改其尺寸。我还会在绘制方法之外设置您的绘制,以便在必须在动画中重绘此 View 时使其速度更快。
我不确定您的代码中的 x
和 y
的用途,但无论您计算什么,很可能都没有意义,因为您的三角函数内有高度和宽度。
因此,您可以通过减去矩形笔划宽度的一半来在矩形内绘制圆弧。然后,您使用同一个矩形来制作供文本放置的圆弧。文本在其基线处绘制(字母的底部,不像 g、j、p 和 y 那样下垂)。
因此,在您的情况下,您可能希望文本适合 View 边界内,因此您应该制作一个比 View 小文本大小的圆弧,而不是用于圆弧的笔画宽度的一半。
我还发现如何放置圆弧矩形存在错误。它位于 View 的左下角。因此,如果您的 View 不是方形的,它将偏离中心。您应该根据中心点进行定位。
由于您执行了两次此计算,因此您可以为其编写一个函数。
private val mRect = RectF()
private val mTextPaint = Paint().apply {
color = resources.getColor(R.color.colorPrimaryDark)
antiAlias = true
style = Paint.Style.FILL_AND_STROKE
textAlign = Paint.Align.LEFT
linearText = true
}
private fun updateCenteredRect(rect: RectF, inset: Int) {
val centerX = measuredWidth / 2
val centerY = measuredHeight / 2
val radius = min(centerX, centerY) - inset
rect.set(centerX - radius, centerY - radius, radius * 2, radius * 2)
}
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
updateCenteredRect(mRect, STROKE_WIDTH / 2)
canvas.drawArc(mRect, 270, 270, false, mDegreesPaint)
val textSize = 30 // You should calculate this based on screen density or it will look too big or small on some devices
mTextPaint.textSize = textSize
updateCenteredRect(mRect, textSize)
Path addArc = new Path().apply {
arcTo(mRect, 250, 270)
}
canvas.drawTextOnPath("text", addArc, 0, 0, mTextPaint)
}
我写这篇文章时并没有真正注意到你的原始代码是用 Java 编写的。我通过 Kotlin 标签找到了你的问题。
关于java - 如何用起始文本绘制圆弧,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60189624/