0

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" />
box
  • 4,450
  • 2
  • 38
  • 38

0 Answers0