Background
I've been searching in plenty of places to find out how to animate a drawable without animating the view and without using the built in drawables.
The reason is that I will need to prepare a customized animation within the drawable, and I might have different requirements for it later.
For now, I'm making a basic animated drawable that just spins a given bitmap inside it.
I've set it on an imageView, but I wish to be able to use it on any kind of view, even customized views that have overridden the onDraw function.
The problem
I can't find out how to show the drawable without being cut, no matter what the size of the view is. Here's what I see:
The code
Here's the code:
private class CircularAnimatedDrawable extends Drawable implements Animatable {
private static final Interpolator ANGLE_INTERPOLATOR = new LinearInterpolator();
private static final int ANGLE_ANIMATOR_DURATION = 2000;
private final RectF fBounds = new RectF();
private float angle = 0;
private ObjectAnimator mObjectAnimatorAngle;
private final Paint mPaint;
private boolean mRunning;
private final Bitmap mBitmap;
public CircularAnimatedDrawable(final Bitmap bitmap) {
this.mBitmap = bitmap;
mPaint = new Paint();
setupAnimations();
}
public float getAngle() {
return this.angle;
}
public void setAngle(final float angle) {
this.angle = angle;
invalidateSelf();
}
@Override
public Callback getCallback() {
return mCallback;
}
@Override
public void draw(final Canvas canvas) {
canvas.save();
canvas.rotate(angle);
canvas.drawBitmap(mBitmap, 0, 0, mPaint);
canvas.restore();
}
@Override
public void setAlpha(final int alpha) {
mPaint.setAlpha(alpha);
}
@Override
public void setColorFilter(final ColorFilter cf) {
mPaint.setColorFilter(cf);
}
@Override
public int getOpacity() {
return PixelFormat.TRANSPARENT;
}
@Override
protected void onBoundsChange(final Rect bounds) {
super.onBoundsChange(bounds);
fBounds.left = bounds.left;
fBounds.right = bounds.right;
fBounds.top = bounds.top;
fBounds.bottom = bounds.bottom;
}
private void setupAnimations() {
mObjectAnimatorAngle = ObjectAnimator.ofFloat(this, "angle", 360f);
mObjectAnimatorAngle.setInterpolator(ANGLE_INTERPOLATOR);
mObjectAnimatorAngle.setDuration(ANGLE_ANIMATOR_DURATION);
mObjectAnimatorAngle.setRepeatMode(ValueAnimator.RESTART);
mObjectAnimatorAngle.setRepeatCount(ValueAnimator.INFINITE);
}
@Override
public void start() {
if (isRunning())
return;
mRunning = true;
mObjectAnimatorAngle.start();
invalidateSelf();
}
@Override
public void stop() {
if (!isRunning())
return;
mRunning = false;
mObjectAnimatorAngle.cancel();
invalidateSelf();
}
@Override
public boolean isRunning() {
return mRunning;
}
}
and the usage :
final ImageView imageView = (ImageView) findViewById(R.id.imageView);
final Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.spinner_76_inner_holo);
final CircularAnimatedDrawable circularAnimatedDrawable = new CircularAnimatedDrawable(bitmap);
circularAnimatedDrawable.setCallback(imageView);
circularAnimatedDrawable.start();
imageView.setImageDrawable(circularAnimatedDrawable);
The question
How can I set it to make the drawable fit the view?
Should I use the bitmap size? the fBounds? both? Or maybe something else?
circularAnimatedDrawable.setCallback(imageView);
, or usesetCallback(null)
, the animation works properly, why? – Cowgill