Marian Pavel
Marian Pavel

Reputation: 2876

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.

Upvotes: 3

Views: 967

Answers (1)

Lewis McGeary
Lewis McGeary

Reputation: 7922

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.

Upvotes: 3

Related Questions