Pavel Marian Pavel Marian - 1 month ago 30
Android Question

Android objectanimator not animating

I have designed today two drawable's of the classic

arrow
and
hamburger
icon to recreate and understand
objectAnimator
in android. The problem occurs when no animation is played but the drawable is changed.

I have created
ic_backarrow.xml
:

<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="48dp"
android:width="48dp"
android:viewportWidth="24"
android:viewportHeight="24">

<path android:strokeColor="@color/blue_ripple"
android:fillColor="@color/blue_ripple"
android:pathData="@string/arrow" />

</vector>


Followed by
ic_menu.xml
:

<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="48dp"
android:width="48dp"
android:viewportWidth="24"
android:viewportHeight="24">

<path android:fillColor="@color/blue_ripple"
android:pathData="@string/menu" />

</vector>


In
strings.xml
I have defined my path's to be more easy to follow:

<string name="arrow">M4,11 H20 V13 H4 V11 M4,11 L12,4 L13.5,5.5 L5.5,12.5 L4,11 M4,13 L12,20 L13.5,18.5 L7.2,13 L4,13</string>
<string name="menu">M3,6 H21 V8 H3 V6 M3,11 L21,11 L21,13 L3,13 L3,11 M3,16 L21,16 L21,18 L3,18 L3,16</string>


I also modified the paths to be able to animate the drawable's: arrow to menu and menu to arrow.

After I have created the
arrow_to_menu.xml
where I define the
objectAnimator
:

<?xml version="1.0" encoding="utf-8"?>

<objectAnimator
xmlns:android="http://schemas.android.com/apk/res/android"
android:propertyName="pathData"
android:valueFrom="@string/arrow"
android:valueTo="@string/menu"
android:duration="@integer/duration"
android:interpolator="@android:interpolator/fast_out_slow_in"
android:valueType="pathType" />


and the
menu_to_arrow.xml
:

<?xml version="1.0" encoding="utf-8"?>

<objectAnimator
xmlns:android="http://schemas.android.com/apk/res/android"
android:propertyName="pathData"
android:valueFrom="@string/menu"
android:valueTo="@string/arrow"
android:duration="@integer/duration"
android:interpolator="@android:interpolator/fast_out_slow_in"
android:valueType="pathType" />


In drawable's I also defined the
animated-vector
with the initial
drawable
and the target
objectAnimator
:

File:
avd_arrow_to_menu.xml
:

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

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

</animated-vector>


And also
avd_menu_to_arrow.xml
:

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

<target
android:name="@string/cross"
android:animation="@animator/menu_to_arrow" />

</animated-vector>


In the project
layout
I have created an
ImageView
:

<ImageView
android:id="@+id/tick_cross"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="@drawable/ic_menu"
android:layout_margin="50dp"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true" />


In the
class
file I look-up for the
ImageView
and import the
AnimatedVectorDrawable's


arrowMenu = (ImageView) findViewById(R.id.tick_cross);
menuToArrow = (AnimatedVectorDrawable) getDrawable(R.drawable.avd_menu_to_arrow);
arrowToMenu = (AnimatedVectorDrawable) getDrawable(R.drawable.avd_arrow_to_menu);

arrowMenu.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
animate(arrowMenu);
}
});


And when the
ImageView
is clicked, it should animate between
hamburger
icon and
arrow
icon:

public void animate(View view) {
AnimatedVectorDrawable drawable = menu ? menuToArrow : arrowToMenu;
arrowMenu.setImageDrawable(drawable);
drawable.start();
menu = !menu;
}


As I said before, there is no animation between arrow and hamburger icon. I tried to change
android:duration
to something bigger like 1000 or something small like 400 but I have the same result.

Sorry for the long post, I really needed to explain every step I done.

Answer

You need to give names to the paths in your VectorDrawables. If we look at your first AnimatedVectorDrawable:

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

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

</animated-vector>

The line android:name="@string/tick" specifies what part of the VectorDrawable you are trying to animate, but if we look at the VectorDrawable, no part of it has been given a name to match that.

To fix that, take the ic_backarrow.xml and add the appropriate name tag:

<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="48dp"
android:width="48dp"
android:viewportWidth="24"
android:viewportHeight="24">

    <path
    android:name="@string/tick"
    android:strokeColor="@color/blue_ripple"
    android:fillColor="@color/blue_ripple"
    android:pathData="@string/arrow" />

</vector>

Then add the appropriate @string/cross name to the path in your other VectorDrawable.