Search code examples
androidandroid-canvasandroid-custom-view

Path arc is thicker than line arc when drawing on canvas


I'm creating a custom View which draws a simple line with a rounded corner using canvas and i can't get the line in the corner to have the same thickness as the straight parts. The path is defined in the onSizeChanged method.

this is how my view looks like:

Line

Here is the view

public class CanvasView extends View {

private Bitmap mBitmap;
private Canvas mCanvas;
private Path mPath;
private Paint mBitmapPaint;
Context context;

public CanvasView(Context c) {
    super(c);
    context = c;
    mPath = new Path();
    mBitmapPaint = new Paint(Paint.DITHER_FLAG);
}

public CanvasView(Context c, AttributeSet attrs) {
    super(c, attrs);
    context = c;
    mPath = new Path();
    mBitmapPaint = new Paint(Paint.DITHER_FLAG);
}

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
    if(mBitmap == null) {

        RectF rectf = new RectF(w - w / 2, h - w / 2, w, h);
        mPath.moveTo(w, 0);
        mPath.lineTo(w, h - w / 2);
        mPath.arcTo(rectf, 0, 90);
        mPath.lineTo(0, h);

        mBitmapPaint.setAntiAlias(true);
        mBitmapPaint.setDither(true);
        mBitmapPaint.setColor(context.getResources().getColor(R.color.siminn_warm_gray));
        mBitmapPaint.setStyle(Paint.Style.STROKE);

        mBitmapPaint.setStrokeWidth(5);
    }
}


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

    canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
    canvas.drawPath(mPath, mBitmapPaint);

}
}

Solution

  • When you're drawing with canvas you have to take in account view padding. onSizeChanged method gives you the witdh and the height of the view without padding. To get padding you can use getPaddingTop(), getPaddingBottom(), getPaddingStart() and getPaddingEnd() function in your View class. This would be the code considering padding:

    @Override
        protected void onSizeChanged(int w, int h, int oldw, int oldh) {
            super.onSizeChanged(w, h, oldw, oldh);
            int realWidth = w - (getPaddingStart() + getPaddingEnd());
            int realHeight = h - (getPaddingTop() + getPaddingBottom());
    
            if (mBitmap == null) {
                RectF rectf = new RectF(realWidth - realWidth / 2, realHeight - realWidth / 2, realWidth, realHeight);
                mPath.moveTo(realWidth, getPaddingTop());
                mPath.lineTo(realWidth, realHeight - realWidth / 2);
                mPath.arcTo(rectf, 0, 90);
                mPath.lineTo(getPaddingStart(), realHeight);
    
                mBitmapPaint.setAntiAlias(true);
                mBitmapPaint.setDither(true);
                mBitmapPaint.setColor(context.getResources().getColor(R.color.siminn_warm_gray));
                mBitmapPaint.setStyle(Paint.Style.STROKE);
                mBitmapPaint.setStrokeWidth(5);
            }
        }