Android transform icon into another one

2019-03-20 04:30发布

问题:

how can I archieve the animation of an icon being tranformed into another one, like the burger into the arrow (navigation drawer) or the pencil into the cross (inbox)? How can I archieve this animation?

回答1:

The icon animation can be achieved using animated-vector

First define your icons as vector drawables. For example, let's take up a tick to cross animation as found here. We will animate ic_tick to ic_cross.

ic_cross.xml

<vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:width="120dp"
        android:height="120dp"
        android:viewportWidth="@integer/viewport_width"
        android:viewportHeight="@integer/viewport_height">

    <group
        android:name="@string/groupTickCross"
        android:pivotX="@integer/viewport_center_x"
        android:pivotY="@integer/viewport_center_y">

        <path
            android:name="@string/cross"
            android:pathData="M6.4,6.4 L17.6,17.6 M6.4,17.6 L17.6,6.4"
            android:strokeWidth="@integer/stroke_width"
            android:strokeLineCap="square"
            android:strokeColor="@color/stroke_color"/>

    </group>

</vector>

ic_tick.xml

<vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:width="120dp"
        android:height="120dp"
        android:viewportWidth="@integer/viewport_width"
        android:viewportHeight="@integer/viewport_height">

    <group
        android:name="@string/groupTickCross"
        android:pivotX="@integer/viewport_center_x"
        android:pivotY="@integer/viewport_center_y">

        <path
            android:name="@string/tick"
            android:pathData="M4.8,13.4 L9,17.6 M10.4,16.2 L19.6,7"
            android:strokeWidth="@integer/stroke_width"
            android:strokeLineCap="square"
            android:strokeColor="@color/stroke_color"/>

    </group>

</vector>

Next we create animators for each of the steps. valueFrom tells the starting point of the animation and valueTo is the final product of the animation. interpolator is the type of interpolation, and you can find a lot more in Android docs. duration specifies the duration of the animation.

tick_to_cross.xml

<objectAnimator
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:propertyName="pathData"
    android:valueFrom="M4.8,13.4 L9,17.6 M10.4,16.2 L19.6,7"
    android:valueTo="M6.4,6.4 L17.6,17.6 M6.4,17.6 L17.6,6.4"
    android:duration="@integer/duration"
    android:interpolator="@android:interpolator/fast_out_slow_in"
    android:valueType="pathType"/>

Now, using animated-vector, we animate the vector. Here <target android:name specifies the target on which the animation has to be done, and android:animation tells the animation to be done.

avd_tick_to_cross.xml

<animated-vector
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/ic_tick">

    <target
        android:name="@string/tick"
        android:animation="@animator/tick_to_cross" />

</animated-vector>

There are a few limitations on how to animate between drawable vectors, but they can be hacked in some way or other, if you have a clear picture what to animate to what, and how the animation should go.