Reputation: 2876
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
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