Android animation. Part 3. SVG, vector and animation control

in #android6 years ago (edited)

In the last article we saw why we need Animator and how to use animations when changing View States. In this article, we'll look at how to use vector image animations.

Simple animation. Animator-the first article
Simple animation. State View-second article
Vector animation. Standard solutions - third article
Vector Drawable animation. Animation control. Hardcore – the fourth article

I think these are the most interesting animations. With a little effort, we can achieve interesting effects. Changes to various icons, the same hamburger turning into a back arrow, are implemented in this way.
The VectorDrawable consists of a Group and Path elements. We will create an animation describing how these elements should be changed.

Let's look at how to turn the play icon into a pause icon.

To do this, we need to draw svg. This can be done using different programs. I used the online service - editor.method.ac. To beautifully animate play in pause we need to split it into two parts – the upper triangle and the lower. Draw, save in svg and add to our project using Vector Assets.

Now we have ic_play.xml:

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

    <group
        android:name="group"
        android:pivotX="64"
        android:pivotY="64">

        <path
            android:name="pause1"
            android:fillColor="#000"
            android:pathData="M 44 32 L 44 64 L 100 64 L 100 64 Z"
            android:strokeColor="#000"
            android:strokeWidth="1" />
        <path
            android:name="pause2"
            android:fillColor="#000"
            android:pathData="M 44 96 L 44 64 L 100 64 L 100 64 Z"
            android:strokeColor="#000"
            android:strokeWidth="1" />
    </group>
</vector>

Note that we have set pivotX and pivotY. This we have indicated the middle of the picture for the correct rotation of our image.

Next you need to create some xml in package res / animator.
top_play_to_pause.xml:

<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="3000"
    android:propertyName="pathData"
    android:valueFrom="M 44 32 L 44 64 L 100 64 L 100 64 Z"
    android:valueTo="M 32 40 L 32 56 L 96 56 L 96 40 Z"
    android:valueType="pathType" />

bottom_play_to_pause.xml:

<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="3000"
    android:propertyName="pathData"
    android:valueFrom="M 44 96 L 44 64 L 100 64 L 100 64 Z"
    android:valueTo="M 32 88 L 32 72 L 96 72 L 96 88 Z"
    android:valueType="pathType" />

Please note that we have described here. We said one path (valueFrom copied from ic_play.xml) must be transformed into the other. Where do we get the other one? Again draw it in the online editor and add it to the project to get the VectorDrawable path that we can insert into valueTo. What will our transformation look like? We can check this very conveniently with shapeshifter.design (if you need help, write comments). It is very convenient that it can give us a ready-made xml, which will only insert into our project.

We also need another xml in package rus/animator - rotate_90.xml:

<objectAnimator
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="3000"
    android:propertyName="rotation"
    android:valueFrom="0"
    android:valueTo="90"
    android:valueType="floatType" />

Now we need to put it all together. Do xml in res/drawable - ic_play_to_pause.xml:

<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/ic_play">
    <target
        android:name="group"
        android:animation="@animator/rotate_90" />
    <target
        android:name="pause1"
        android:animation="@animator/top_play_to_pause" />
    <target
        android:name="pause2"
        android:animation="@animator/bottom_play_to_pause" />
</animated-vector>

The Studio may swear that the animated-vector can only be used in API>21, but don't pay attention to that :) What did we do here? We have linked different objectAnimator to different parts of our ic_play.the xml via the android:name.

What next?
Go to activity_main.xml and add our icon there:

<android.support.v7.widget.AppCompatImageViewapp:srcCompat="@drawable/ic_play_to_pause" />

Note that we use the control from the android support library and also specify drawable in app:srcCompat – all this will allow to use animated-vector in API projects >= 15.
All that's left is to start the animation. In the code, write only one line:

((Animatable) imageView.getDrawable()).start();

In the project settings do not forget to put a flag:

android {
    compileSdkVersion 26
    defaultConfig {
        ...
        vectorDrawables.useSupportLibrary = true
        }
    ...
}

What did we get in the end? See result ↓
ezgif.gif
Unfortunately, we can't control the animation in standard ways. We can't bind it to any event, such as a swipe, so that the icon changes to the same hamburger when you open Navigation Drawer. It turns out that vector animation cannot be controlled by? Not exactly, but that's a different story.

Sort:  

Congratulations @mstorm! You have completed some achievement on Steemit and have been rewarded with new badge(s) :

Award for the number of upvotes

Click on the badge to view your Board of Honor.
If you no longer want to receive notifications, reply to this comment with the word STOP

Do you like SteemitBoard's project? Then Vote for its witness and get one more award!

Congratulations @mstorm! You have completed the following achievement on the Steem blockchain and have been rewarded with new badge(s) :

Award for the number of upvotes

Click on the badge to view your Board of Honor.
If you no longer want to receive notifications, reply to this comment with the word STOP

Do not miss the last post from @steemitboard:

SteemitBoard - Witness Update
SteemFest³ - SteemitBoard support the Travel Reimbursement Fund.

Support SteemitBoard's project! Vote for its witness and get one more award!

Congratulations @mstorm! You have completed the following achievement on the Steem blockchain and have been rewarded with new badge(s) :

You made more than 1250 upvotes. Your next target is to reach 1500 upvotes.

Click here to view your Board of Honor
If you no longer want to receive notifications, reply to this comment with the word STOP

Support SteemitBoard's project! Vote for its witness and get one more award!

Congratulations @mstorm! You received a personal award!

Happy Birthday! - You are on the Steem blockchain for 1 year!

You can view your badges on your Steem Board and compare to others on the Steem Ranking

Do not miss the last post from @steemitboard:

Are you a DrugWars early adopter? Benvenuto in famiglia!
Vote for @Steemitboard as a witness to get one more award and increased upvotes!

Congratulations @mstorm! You received a personal award!

Happy Steem Birthday! - You are on the Steem blockchain for 2 years!

You can view your badges on your Steem Board and compare to others on the Steem Ranking

Do not miss the last post from @steemitboard:

Downvote challenge - Add up to 3 funny badges to your board
Vote for @Steemitboard as a witness to get one more award and increased upvotes!