且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

在画布上用Android中不同长度的文本绘制弯曲文本

更新时间:2023-11-24 11:23:46

这可以通过基于文本宽度更改x和y位置来完成

This can be done by varying the x and y positions based on textwidth

定义变量

private Rect textBounds;
private int mTextWidth, mTextHeight,centerX,centerY;

在customview的构造函数中添加以下内容

Add the below in the constructor of customview

textBounds = new Rect();

tPaint.getTextBounds(QUOTE, 0, QUOTE.length(), textBounds);
mTextWidth = Math.round(tPaint.measureText(QUOTE.toString())); // Use measureText to calculate width
mTextHeight = textBounds.height(); // Use height from getTextBounds()

然后在onDraw中

canvas.drawCircle(centerX,centerY,150,mCirlcePaint);
circle.addCircle(centerX, centerY, 150, Path.Direction.CW); 
// Note the 0 that's y offset. textdraw at circumference of the circle. Changing y you probably need to change the radius as well i guess.
canvas.drawTextOnPath(QUOTE, circle, (centerX)-(mTextWidth / 2f), 0, tPaint);

centerX,centerY是圆的中心,即canvaswidht/2和canvasHeight/2.我画了一个圆圈供参考

centerX,centerY are the center of the circle ie canvaswidht/2 and canvasHeight/2. I drew a circle for reference

打招呼的结果

获取更大文本的结果

对于数字

对评论中的问题

涉及的数学是使用文本长度计算半圆 radius =(float)((mTextWidth)/(Math.PI)).如果文本长度大于画布,则需要减小文本大小或使用完整的圆 radius =(float)((mTextWidth)/(2 *(Math.PI))).很少有其他情况下您可以考虑正确绘制文本.

The math involved is in calculating the semi circle using text length radius = (float) ((mTextWidth) / (Math.PI)). If text length is greater than your canvas you need to reduce the text size or use the full circle radius = (float) ((mTextWidth) / (2*(Math.PI))). Few other edge case you can consider to draw the text properly.

公共类GraphicsView扩展了View {

public class GraphicsView extends View {

private String QUOTE = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
private Path circle;
private Paint mCirlcePaint;
private Paint tPaint;
private Rect textBounds;
private int mTextWidth, mTextHeight, centerX, centerY;

private float radius;

public GraphicsView(Context context) {
    super(context);
    circle = new Path();

    tPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    tPaint.setStyle(Paint.Style.FILL_AND_STROKE);
    tPaint.setColor(Color.BLACK);
    tPaint.setTextSize(100f);
    textBounds = new Rect();

    tPaint.getTextBounds(QUOTE, 0, QUOTE.length(), textBounds);
    mTextWidth = Math.round(tPaint.measureText(QUOTE.toString())); // Use measureText to calculate width
    mTextHeight = textBounds.height(); // Use height from getTextBounds()

    mCirlcePaint = new Paint();
    mCirlcePaint.setStyle(Paint.Style.FILL);
    mCirlcePaint.setColor(Color.GREEN);

    radius = (float) ((mTextWidth) / (Math.PI));

}

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
    centerX = w / 2;
    centerY = h / 2;

}

@Override
protected void onDraw(Canvas canvas) {

    canvas.rotate(180, getWidth() / 2, getHeight() / 2);
    canvas.drawCircle(centerX, centerY, radius, mCirlcePaint);
    circle.addCircle(centerX, centerY, radius, Path.Direction.CW);
    canvas.drawTextOnPath(QUOTE, circle, 0, 0, tPaint);

   }

}