Search code examples
androidandroid-animationandroid-vectordrawable

How to animate the Particular Part of the Icon in Vector Drawable?


Am new to Vector Drawable Animation, in that i have Notification Active icon in Vector Drawable.

Notification Icon Vector Path Code:-

<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="140dp"
android:height="140dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
    android:fillColor="@color/dark_grey"
    android:pathData="M7.58,4.08L6.15,2.65C3.75,4.48 2.17,7.3 2.03,10.5h2c0.15,-2.65 1.51,-4.97 3.55,-6.42zM19.97,10.5h2c-0.15,-3.2 -1.73,-6.02 -4.12,-7.85l-1.42,1.43c2.02,1.45 3.39,3.77 3.54,6.42zM18,11c0,-3.07 -1.64,-5.64 -4.5,-6.32L13.5,4c0,-0.83 -0.67,-1.5 -1.5,-1.5s-1.5,0.67 -1.5,1.5v0.68C7.63,5.36 6,7.92 6,11v5l-2,2v1h16v-1l-2,-2v-5zM12,22c0.14,0 0.27,-0.01 0.4,-0.04 0.65,-0.14 1.18,-0.58 1.44,-1.18 0.1,-0.24 0.15,-0.5 0.15,-0.78h-4c0.01,1.1 0.9,2 2.01,2z" />

The Icon Will be Like this

enter image description here

Want To Animate the Outer Ring only using Vector drawable Animation. Can one Guide me to Learn Vector Drawable animation.


Solution

  • VectorDrawable paths use the same syntax as SVG paths. Following those instructions, you can see that the path traces out the left and right ring parts first, followed by the body and bottom bit.

    In order to animate the ringer separately from the body, split it out into its own path.

    <!-- The ringer -->
    <path
        android:fillColor="@color/dark_grey"
        android:pathData="M7.58,4.08L6.15,2.65C3.75,4.48 2.17,7.3 2.03,10.5h2c0.15,-2.65 1.51,-4.97 3.55,-6.42zM19.97,10.5h2c-0.15,-3.2 -1.73,-6.02 -4.12,-7.85l-1.42,1.43c2.02,1.45 3.39,3.77 3.54,6.42z" />
    <!-- The body -->
    <path
        android:fillColor="@color/dark_grey"
        android:pathData="M18,11c0,-3.07 -1.64,-5.64 -4.5,-6.32L13.5,4c0,-0.83 -0.67,-1.5 -1.5,-1.5s-1.5,0.67 -1.5,1.5v0.68C7.63,5.36 6,7.92 6,11v5l-2,2v1h16v-1l-2,-2v-5zM12,22c0.14,0 0.27,-0.01 0.4,-0.04 0.65,-0.14 1.18,-0.58 1.44,-1.18 0.1,-0.24 0.15,-0.5 0.15,-0.78h-4c0.01,1.1 0.9,2 2.01,2z" />
    

    Then we need to give that part a name so the animator can attach to it, and wrap it in a <group> if you want to animate its position or rotation. I eyeballed the pivot point for rotation.

    <group android:name="ringer" android:pivotX="12" android:pivotY="10.5">
        <path
            android:fillColor="@color/dark_grey"
            android:pathData="M7.58,4.08L6.15,2.65C3.75,4.48 2.17,7.3 2.03,10.5h2c0.15,-2.65 1.51,-4.97 3.55,-6.42zM19.97,10.5h2c-0.15,-3.2 -1.73,-6.02 -4.12,-7.85l-1.42,1.43c2.02,1.45 3.39,3.77 3.54,6.42z" />
    </group>
    

    Now you can embed it into an AnimatedVectorDrawable and attach an animation to that group.

    <?xml version="1.0" encoding="utf-8"?>
    <animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:aapt="http://schemas.android.com/aapt">
        <aapt:attr name="android:drawable">
            <vector android:width="140dp" android:height="140dp"
                android:viewportWidth="24.0" android:viewportHeight="24.0">
                <group android:name="ringer" android:pivotX="12" android:pivotY="10.5">
                    <path
                        android:fillColor="@color/dark_grey"
                        android:pathData="M7.58,4.08L6.15,2.65C3.75,4.48 2.17,7.3 2.03,10.5h2c0.15,-2.65 1.51,-4.97 3.55,-6.42zM19.97,10.5h2c-0.15,-3.2 -1.73,-6.02 -4.12,-7.85l-1.42,1.43c2.02,1.45 3.39,3.77 3.54,6.42z" />
                </group>
                <path
                    android:fillColor="@color/dark_grey"
                    android:pathData="M18,11c0,-3.07 -1.64,-5.64 -4.5,-6.32L13.5,4c0,-0.83 -0.67,-1.5 -1.5,-1.5s-1.5,0.67 -1.5,1.5v0.68C7.63,5.36 6,7.92 6,11v5l-2,2v1h16v-1l-2,-2v-5zM12,22c0.14,0 0.27,-0.01 0.4,-0.04 0.65,-0.14 1.18,-0.58 1.44,-1.18 0.1,-0.24 0.15,-0.5 0.15,-0.78h-4c0.01,1.1 0.9,2 2.01,2z" />
            </vector>
        </aapt:attr>
        <target android:name="ringer">
            <aapt:attr name="android:animation">
                <objectAnimator
                    android:duration="50"
                    android:propertyName="rotation"
                    android:valueFrom="-15"
                    android:valueTo="15"
                    android:repeatCount="infinite"
                    android:repeatMode="reverse"/>
            </aapt:attr>
        </target>
    </animated-vector>
    

    Don't forget to call Animatable2#start() on the drawable when you want it to run.