suku
suku

Reputation: 10939

Animated Vector Drawable for on click rotation of arrow

I need to have an expandable recycler view. I am planning to use an animated vector drawable for the collapse and expand arrow animation.

There is this setExpandCollapseListener using which I can start the rotation. How to use Animated Vector Drawable to get the same effect as shown below?

Vector drawable for expand button:

<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:viewportWidth="306"
android:viewportHeight="306"
android:width="306dp"
android:height="306dp">
<path
    android:pathData="M153 247.35L306 94.35 270.3 58.65 153 175.95 35.7 58.65 0 94.35Z"
    android:fillColor="#000000" />
</vector>

Vector drawable for collapse button:

<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:viewportWidth="306"
android:viewportHeight="306"
android:width="306dp"
android:height="306dp">
<path
    android:pathData="M270.3 247.35L306 211.65 153 58.65 0 211.65 35.7 247.35 153 130.05Z"
    android:fillColor="#000000" />
</vector>

enter image description here

Upvotes: 7

Views: 8764

Answers (2)

Akshay Sahai
Akshay Sahai

Reputation: 2350

All you need is just one line of code -

view.animate().rotationBy(degree_of_rotation).setDuration(duration_in_milliseconds).start();

Upvotes: 19

Anton Holovin
Anton Holovin

Reputation: 5673

1. Add vector images

We also need to wrap path in group because group is the part of vector resource that will be animated. You can set any name for a group.

res/drawable/ic_arrow_down.xml

<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:viewportWidth="306"
    android:viewportHeight="306"
    android:width="306dp"
    android:height="306dp">

    <group
     android:name="arrow"
     android:pivotX="153"
     android:pivotY="153">
        <path
            android:pathData="M153 247.35L306 94.35 270.3 58.65 153 175.95 35.7 58.65 0 94.35Z"
            android:fillColor="#000000" />
    </group>
</vector>

res/drawable/ic_arrow_top.xml

<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:viewportWidth="306"
    android:viewportHeight="306"
    android:width="306dp"
    android:height="306dp">

    <group
     android:name="arrow"
     android:pivotX="153"
     android:pivotY="153">
         <path
             android:pathData="M270.3 247.35L306 211.65 153 58.65 0 211.65 35.7 247.35 153 130.05Z"
             android:fillColor="#000000" />
    </group>
</vector>

2. Add animator

res/animator/animation_arrow_rotation.xml

<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="@android:integer/config_shortAnimTime"
    android:propertyName="rotation"
    android:valueFrom="0"
    android:valueTo="180" />

3. Add animated vector drawables

<target> references to the group's name.

res/drawable/ic_animated_arrow_down.xml

<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/ic_arrow_down">

    <target
        android:name="arrow"
        android:animation="@animator/animation_arrow_rotation" />
</animated-vector>

res/drawable/ic_animated_arrow_up.xml

<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/ic_arrow_up">

    <target
        android:name="arrow"
        android:animation="@animator/animation_arrow_rotation" />
</animated-vector>

4. Add some code to Adapter

Init ImageView in ParentViewHolder's inheritor:

void bind(UiModel uiModel) {
    arrowImageView.setImageResource(isExpanded() ? R.drawable.ic_animated_arrow_down :
            R.drawable.ic_animated_arrow_up);

    // some other code 
}

and override onExpansionToggled:

@Override
public void onExpansionToggled(boolean expanded) {
    super.onExpansionToggled(expanded);

    arrowImageView.setImageResource(expanded ? R.drawable.ic_animated_arrow_down :
            R.drawable.ic_animated_arrow_up);
    AnimatedVectorDrawableCompat drawable = (AnimatedVectorDrawableCompat) arrowImageView.getDrawable();

    drawable.registerAnimationCallback(new Animatable2Compat.AnimationCallback() {
        @Override
        public void onAnimationEnd(Drawable ignored) {
            drawable.clearAnimationCallbacks();

            arrowImageView.setImageResource(expanded ? R.drawable.ic_animated_arrow_up :
                    R.drawable.ic_animated_arrow_down);
        }
    });

    drawable.start();
}

By the way, you can define AnimatedVectorDrawable XML resources in one XML file. Details here.

Upvotes: 10

Related Questions