Question

I want to show the progress of a file upload by filling an arc untill it hits 100% (a circle). This is quite easy to do. I only needed it to rotate animated as well. When I did that I came to the conclusion that the circle is not perfectly round cause it was bouncing a bit.

Below you'll see the arc when it is at 100%. the original image

And here a green overlay added with Photoshop which displays the imperfection of the circle. the image with a perfect (photoshop) circle on top of it

Why is the arc/circle not round? Is this anti-aliasing? Beside that when I'm just redraw the arc on different places at the frame rate it still shows the bouncing effect.

The "debugging" code I use:

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

    Path path = new Path();
    RectF drawBounds = new RectF(mBounds.left, mBounds.top, mBounds.right, mBounds.bottom);

    if(mProgress != 100) {
        path.arcTo(drawBounds, mStartDegree, mProgress * 3.6f, true);
        canvas.drawPath(path, mLoaderPaint);
    }

    if (mStartDegree >= 359)
        mStartDegree = 0;
    else
        mStartDegree ++;

    invalidate();
}
Was it helpful?

Solution

seems that arc drawing routine is somewhat broken, run my code and wait till angle is < 270 degs or less:

class V extends View implements Runnable {

    private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    private RectF mRect = new RectF();
    private float mStartAngle;
    private float mAngle;
    private Xfermode mClearMmode = new PorterDuffXfermode(Mode.CLEAR);

    public V(Context context) {
        super(context);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        mRect.set(0, 0, w, w);
        getHandler().post(this);
    }

    @Override
    protected void onDetachedFromWindow() {
        Log.d(TAG, "onDetachedFromWindow ");
        super.onDetachedFromWindow();
        getHandler().removeCallbacks(this);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        mPaint.setColor(0xff00aa00);
        mPaint.setXfermode(null);
        canvas.drawOval(mRect, mPaint);

        mPaint.setXfermode(mClearMmode);
        canvas.drawArc(mRect, mStartAngle, mAngle, true, mPaint);
    }

    @Override
    public void run() {
        mStartAngle += 3.65;
        mAngle += 0.2f;
        invalidate();
        getHandler().postDelayed(this, 20);
    }
}

the good news is that you will easily find out how to use this code to get what you want

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top