I want to create a rotating progress image, and wonder what\'s the best way to proceed. I can make it work with an animation list with for example 12 images changing every 1
Thank @vokilam. This similar solution (a custom view that rotates automatically) uses
dynamically in its implementation:
public class FramesAnimatorView extends AppCompatImageView {
private int framesCount;
private int duration;
private Bitmap frameBitmap;
public FramesAnimatorView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context, attrs);
}
public FramesAnimatorView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
public FramesAnimatorView(Context context) { super(context); }
private void init(Context context, AttributeSet attrs) {
final TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.FramesAnimatorView);
framesCount = typedArray.getInt(R.styleable.FramesAnimatorView_framesCount, 12);
duration = typedArray.getInt(R.styleable.FramesAnimatorView_duration, 1200);
typedArray.recycle();
// Method 1: Use as Animation (RotateAnimation) and startAnimation() (Rotate view itself).
//method1(framesCount, duration);
// Method 2: Use as Drawable (RotateDrawable) and ObjectAnimator. Usable for API 21+ (because of using RotateDrawable.setDrawable).
//method2();
// Method 3 (Recommended): Use (AnimationDrawable) dynamically.
final int frameDuration = this.duration / framesCount;
final AnimationDrawable animationDrawable = (AnimationDrawable) getDrawable();
for (int i = 0; i < framesCount; i++)
animationDrawable.addFrame(
new RotatedDrawable(frameBitmap, i * 360f / framesCount, getResources()),
frameDuration);
animationDrawable.start();
}
@Override public void setImageResource(int resId) { //info();
frameBitmap = BitmapFactory.decodeResource(getResources(), resId);
super.setImageDrawable(new AnimationDrawable());
}
@Override public void setImageDrawable(@Nullable Drawable drawable) { //info();
frameBitmap = drawableToBitmap(drawable);
super.setImageDrawable(new AnimationDrawable());
}
@Override public void setImageBitmap(Bitmap bitmap) { //info();
frameBitmap = bitmap;
super.setImageDrawable(new AnimationDrawable());
}
/**
* See @android-developer's answer on stackoverflow.com.
*/
private static class RotatedDrawable extends BitmapDrawable {
private final float degrees;
private int pivotX;
private int pivotY;
RotatedDrawable(Bitmap bitmap, float degrees, Resources res) {
super(res, bitmap);
pivotX = bitmap.getWidth() / 2;
pivotY = bitmap.getHeight() / 2;
this.degrees = degrees;
}
@Override public void draw(final Canvas canvas) {
canvas.save();
canvas.rotate(degrees, pivotX, pivotY);
super.draw(canvas);
canvas.restore();
}
}
/**
* See @André's answer on stackoverflow.com.
*/
@NonNull private static Bitmap drawableToBitmap(Drawable drawable) {
final Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
final Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
return bitmap;
}
}
See Android-FramesAnimatorView on GitHub for full (and probably more updated) source code.