Hy, I'm trying to do an animation of a circle drawn on canvas. I can do that pretty easily with ObjectAnimator, however I'd like to start the animation when the view finishes loading or finishes drawing. If I start the animation in init(), the animation property will be "ahead" of the actual drawing, so I need to start it on a callback when the whole view is properly set up. I could do that onMeasure() or onSizeChanged() but those two get called too many times and if i have nested layouts it doesn't work properly. If I use startDelay() it works but I don't think that is an accurate procedure.
Here is a basic custom view class with animation property that changes the radius of a circle.
public class CustomView extends View {
private static final String TAG = CustomView.class.toString();
public CustomView(final Context context) {
super(context);
init(context);
}
public CustomView(final Context context, final AttributeSet attrs) {
super(context, attrs);
init(context);
}
public CustomView(final Context context, final AttributeSet attrs, final int defStyle) {
super(context, attrs, defStyle);
init(context);
}
private void init(final Context context) {
// OUTER CIRCLE PAINT
mPaint = new Paint();
// Adds anti-aliasing to drawed elements
mPaint.setAntiAlias(true);
mPaint.setFilterBitmap(true);
mPaint.setStrokeWidth(1);
mPaint.setStrokeCap(Paint.Cap.SQUARE);
mPaint.setStyle(Paint.Style.FILL);
final int animationTime = getResources().getInteger(ANIMATION_TIME_ID);
progressAnimator = ObjectAnimator.ofFloat(this, "animProgress", 0f, 0f);
progressAnimator.setDuration(animationTime);
Log.d(TAG, "Init ended");
//startAnimationCircle(50f);
}
@Override
public void onDraw(final Canvas canvas) {
super.onDraw(canvas);
canvas.drawCircle(this.getWidth()/2, this.getHeight()/2, animProgress, mPaint);
}
@Override
protected void onSizeChanged (int w, int h, int oldw, int oldh) {
//startAnimationCircle(50f);
}
/**
* onMeasure() is called automatically right after a call to measure()
*/
@Override
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//startAnimationCircle(50f);
}
private Paint mPaint;
private static final int ANIMATION_TIME_ID = android.R.integer.config_mediumAnimTime;
private float animProgress;
private ObjectAnimator progressAnimator;
public float getAnimProgress() {
return animProgress;
}
public void setAnimProgress(float animProgress) {
this.animProgress = animProgress;
this.invalidate();
}
public void startAnimationCircle(float size) {
progressAnimator.setFloatValues(animProgress, size);
//progressAnimator.setStartDelay(2000);
progressAnimator.start();
}
}
And the XML also.
<com.your-package.CustomView
android:layout_width="match_parent"
android:layout_height="match_parent" />