Search code examples
androidbitmapautomatic-ref-countingprogressclip

How do I draw a partial bitmap-arc? Like a circular progress wheel, but with a bitmap that gets more and more displayed.


What I am searching for, is a view that reveals an image in a clockwise circular fashion. When the progress is 25% the first 90 degrees should be revealed and when its 100% the full 360 degrees should be drawn.

It is very close to using the canvas.drawArc(), but this method only works with Paint objects, not bitmaps.

Other answers also only work with full colors: How To Make Circle Custom Progress Bar in Android

I have found it to be a very hard problem, I hope someone has a solution.


Solution

  • tre this:

    public class MyView extends View {
    
        private Bitmap mBitmap;
        private Paint mPaint;
        private RectF mOval;
        private float mAngle = 135;
        private Paint mTextPaint;
    
        public MyView(Context context) {
            super(context);
            // use your bitmap insted of R.drawable.ic_launcher
            mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
            mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
            mOval = new RectF();
            mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
            mTextPaint.setTextSize(48);
            mTextPaint.setTextAlign(Align.CENTER);
            mTextPaint.setColor(0xffffaa00);
            mTextPaint.setTypeface(Typeface.DEFAULT_BOLD);
        }
    
        @Override
        protected void onSizeChanged(int w, int h, int oldw, int oldh) {
            Matrix m = new Matrix();
            RectF src = new RectF(0, 0, mBitmap.getWidth(), mBitmap.getHeight());
            RectF dst = new RectF(0, 0, w, h);
            m.setRectToRect(src, dst, ScaleToFit.CENTER);
            Shader shader = new BitmapShader(mBitmap, TileMode.CLAMP, TileMode.CLAMP);
            shader.setLocalMatrix(m);
            mPaint.setShader(shader);
            m.mapRect(mOval, src);
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            canvas.drawColor(0xff0000aa);
            canvas.drawArc(mOval, -90, mAngle, true, mPaint);
            canvas.drawText("click me", getWidth() / 2, getHeight() / 2, mTextPaint);
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            float w2 = getWidth() / 2f;
            float h2 = getHeight() / 2f;
            mAngle = (float) Math.toDegrees(Math.atan2(event.getY() - h2, event.getX() - w2));
            mAngle += 90 + 360;
            mAngle %= 360;
            invalidate();
            return true;
        }
    }