Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android 6.0 incorrectly handles drawCircle method

In my app I need to draw circles using bitmap and the drawCircle() method.

Everything was working fine and exactly as it should up until Android 6.0.

It still draws circles on all the previous versions, but draws rectangles when I use the app on 6.0. But if I change it to be filled, it draws a circle both in api 22 and api 23. Anyone has the same problem or any idea why this happens?

Here is the source code and a screenshot (app running on API 23 on the left, and API 22 on the right). same app on different api's

 public final class Circle1View extends View {

    private float xCenter, yCenter;
    private Bitmap grid = null;

    public Circle1View (Context context) {
        super(context);
        init();
    }

    private void init() {
        setLayerType(View.LAYER_TYPE_SOFTWARE, null);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        int w = getWidth();
        int h = getHeight();
        xCenter = w / 2;
        yCenter = h / 2;

        drawBitmaps(w, h);

        canvas.translate(xCenter, yCenter);
        canvas.scale(xCenter, yCenter);

        canvas.drawBitmap(grid, null, new RectF(-1, -1, 1, 1), null);
    }


    private void drawBitmaps(int w, int h) {

        grid  = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas();

        canvas.translate(xCenter, yCenter);
        canvas.scale(xCenter, yCenter);

        Paint gridPaint = new Paint();

        gridPaint.setStrokeWidth(0.01f);
        // Works with FILL
        // gridPaint.setStyle(Paint.Style.FILL);
        gridPaint.setStyle(Paint.Style.STROKE);

        canvas.setBitmap(grid);

        canvas.drawCircle(0, 0, 0.5f, gridPaint);


    }
}
like image 553
Darja Orlova Avatar asked Oct 28 '15 14:10

Darja Orlova


1 Answers

I think it has something to do with the scaling and translation you do. Imagine the circle that is drawn is so small, it only takes 4 pixels. When enlarging this back to the full size, you are left with 4 straight lines between these pixels.

When I change the stroke width to 0.04f, the issue is gone. I would suggest you simplify your code by drawing on the supplied Canvas directly:

@Override
protected void onDraw(Canvas canvas) {
    int w = getWidth();
    int h = getHeight();
    xCenter = w / 2;
    yCenter = h / 2;

    Paint gridPaint = new Paint();

    gridPaint.setStrokeWidth(1f);
    gridPaint.setStyle(Paint.Style.STROKE);

    canvas.drawCircle(xCenter, yCenter, w/4, gridPaint);
}

As for your question about the difference between API levels: Marshmallow introduced changes for drawBitmap(). You can have a look at the respective source code for Lollipop and Marshmallow.

like image 185
Thomas Avatar answered Oct 15 '22 05:10

Thomas