Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android drawing rectangle timer with animation

I'm trying to have an animation drawing stroke rectangle:

Rounded Rectangle Stroke Animation

Any kickstart for this issue will be helpful. Using Views,Canvas anything.

Thanks

like image 734
The Butcher Avatar asked May 07 '13 07:05

The Butcher


2 Answers

Ok, here's is something to get you started, it is not the complete solution but from here you can complete your task.

What I'm doing is dynamically updating my mask according to the progress. I just drew a line, but in your case you need to draw four lines that will make a masked rectangle according to the progress. Here's the code let me know if that helps:

public class DrawView extends View implements Runnable {

Bitmap mProgressBitmap;
Bitmap mMaskProgressBitmap;
Bitmap mResultBitmap;

Canvas mTempCanvas;
Canvas mMaskCanvas;

Paint mPaint;

Paint mWhitePaint;

Handler mHandler = new Handler();

float mProgress = 0;

static final long FRAME_TIME = 50;

public DrawView(Context context, AttributeSet attrs) {
    super(context, attrs);

    InputStream resource = getResources().openRawResource(R.drawable.timer);
    mProgressBitmap = BitmapFactory.decodeStream(resource);

    mMaskProgressBitmap = Bitmap.createBitmap(mProgressBitmap.getWidth(), mProgressBitmap.getHeight(), Bitmap.Config.ARGB_8888);
    mMaskCanvas = new Canvas(mMaskProgressBitmap);
    mMaskCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);

    mResultBitmap = Bitmap.createBitmap(mProgressBitmap.getWidth(), mProgressBitmap.getHeight(), Bitmap.Config.ARGB_8888);

    mTempCanvas = new Canvas(mResultBitmap);

    mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
    mPaint.setDither(true);

    mWhitePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    mWhitePaint.setColor(Color.WHITE);
    mWhitePaint.setStrokeWidth(50);

    mHandler.postDelayed(this, FRAME_TIME);
}

@Override
public void onDraw(Canvas canvas) {

    mTempCanvas.drawBitmap(mMaskProgressBitmap, 0, 0, null);
    mTempCanvas.drawBitmap(mProgressBitmap, 0, 0, mPaint);

    canvas.drawBitmap(mResultBitmap, 0, 0, null);
}

@Override
public void run() {

    mProgress += 0.01f;

    mMaskCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
    mMaskCanvas.drawLine(0, 0, (float)mProgressBitmap.getWidth() * mProgress, 0, mWhitePaint);

    this.invalidate();

    mHandler.postDelayed(this, FRAME_TIME);
}

}
like image 145
Oren Bengigi Avatar answered Nov 10 '22 17:11

Oren Bengigi


I think you can achieve something very basic with AnimationDrawable and create a frame-by-frame animation. Obviously, the more frame you use the smoother it becomes.

<!-- Animation frames are wheel0.png -- wheel5.png files inside the
 res/drawable/ folder -->
 <animation-list android:id="@+id/selected" android:oneshot="false">
    <item android:drawable="@drawable/wheel0" android:duration="50" />
    <item android:drawable="@drawable/wheel1" android:duration="50" />
    ...
 </animation-list>

Other option would be to use ClipDrawable to mask your rectangle and animate the mask. There is a tutorial to Customize Your Progress Bar which uses the same logic for your purpose. I hope so.

Look at this sample. It's flash but it uses the same clipping technique to achieve a stroking effect.

If I'm not mistaken, Android Canvas has a few clip methods to mask your graphics: clipPath, clipRect and clipRegion. But I'm not sure if it can be animated or not. Check them out.

like image 1
Sam R. Avatar answered Nov 10 '22 19:11

Sam R.