Android circle checkmark animation

Ionut Negru picture Ionut Negru · Aug 22, 2016 · Viewed 20.1k times · Source

I'm trying to achieve something similar to the BEMAnimationTypeStroke which can be found in the iOS library BEMCheckBox.

I've tried using an animated vector drawable to achieve this, but I do not know how to animate the checkmark inside the circle from an 0 start point to the final position. (the circle can be static, I'm looking to animate the check mark). This is the implementation I tried for this:

drawable/vector_drawable_ic_check_circle_white_48px.xml

    <path
            android:name="check"
            android:fillColor="#FFFFFF"
            android:pathData="M37.1,13.6L18.4,32.3h1.7l-8.5-8.5L10,25.5l8.5,8.5l0.8,0.8l0.8-0.8l18.7-18.7L37.1,13.6L37.1,13.6z"/>
    <path
            android:name="circle"
            android:fillColor="#FFFFFF"
            android:pathData="M24,48c13.3,0,24-10.7,24-24S37.3,0,24,0S0,10.7,0,24S10.7,48,24,48L24,48z
M24,45.6
C12.1,45.6,2.4,35.9,2.4,24S12.1,2.4,24,2.4S45.6,12.1,45.6,24S35.9,45.6,24,45.6L24,45.6z"/>
</vector>

anim/transform.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <objectAnimator
            android:duration="1000"
            android:propertyName="fillColor"
            android:valueFrom="@color/transparent"
            android:valueTo="@color/white"/>
</set>

drawable/animation.xml

<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:drawable="@drawable/vector_drawable_ic_check_circle_white_48px">
    <target
            android:name="check"
            android:animation="@anim/change_color"/>
</animated-vector>

And when the layout is set, I start the animation using:

ImageView mCpuImageView = (ImageView) findViewById(R.id.animated_check);
Drawable drawable = mCpuImageView.getDrawable();
if (drawable instanceof Animatable) {
    ((Animatable) drawable).start();
}

Can anyone help me with this? Is there an easier way to achieve this (Custom view or existing library)?

The idea is that I want to have an check mark in a circle and I want to animate the path of the check mark. When it is displayed only the circle will be visible and afterwards to animate the check mark creation. If other customizations, like animating the circle at the same time the check mark is animating are easy to implement It would be event better, but at first I want to animate the check mark only.

LE: In the end I've chosen to go with the approach of creating the animation manually via an custom View. If anyone has an idea of how I can achieve this via vector drawable it woul be a nice development practice. Thank you.

Answer

s-hunter picture s-hunter · Apr 10, 2017

I was looking for the same, this post pretty much explains it all. The code from that post:

drawable/check_mark.xml

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="24dp"
    android:height="24dp"
    android:viewportHeight="24.0"
    android:viewportWidth="24.0">
    <group android:name="background">
        <path
            android:name="circle"
            android:fillColor="@color/colorPrimary"
            android:pathData="M12,12m-10,0a10,10 0,1 1,20 0a10,10 0,1 1,-20 0" />
    </group>
    <group android:name="check">
        <path
            android:name="tick"
            android:pathData="M6,11 l0,0 l0,0"
            android:strokeColor="@color/colorAccent"
            android:strokeWidth="1" />
    </group>

</vector>

drawable-v21/animated_check.xml

<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/check_mark">
    <target
        android:name="tick"
        android:animation="@anim/check_animation" />
</animated-vector>

anim/check_animation.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/accelerate_interpolator"
    android:ordering="sequentially"
    android:shareInterpolator="false">
    <!-- Step 1 -->
    <objectAnimator
        android:duration="@android:integer/config_shortAnimTime"
        android:propertyName="pathData"
        android:valueFrom="M6,11 l0,0 l0,0"
        android:valueTo="M6,11 l3.5,4 l0,0"
        android:valueType="pathType" />
    <!-- Step 2 -->
    <objectAnimator
        android:duration="@android:integer/config_shortAnimTime"
        android:propertyName="pathData"
        android:valueFrom="M6,11 l3.5,4 l0,0"
        android:valueTo="M6,11 l3.5,4 l8,-7"
        android:valueType="pathType" />
</set>

Usage

Layout XML

<ImageView
    android:id="@+id/imageView"
    android:layout_width="100dp"
    android:layout_height="100dp"
    android:visibility="visible"
    app:srcCompat="@drawable/animated_check" />

Java Class

mImgCheck = (ImageView) findViewById(R.id.imageView);
((Animatable) mImgCheck.getDrawable()).start();