Vector Graphics on Android

In this tutorial you will learn what Scalable Vector Graphics are and how to create and manipulate Vector Graphics on Android By Kyle Jablonski.

Leave a rating/review
Download materials
Save for later
Share
You are currently viewing page 4 of 4 of this article. Click here to view the first page.

Creating a Loader Using AnimatedVectorDrawable

Start by creating a file called ic_vd_loader.xml in the drawable folder and paste in the following vector drawable:

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

  <!-- 2 -->
  <group
    android:name="scaleGroup"
    android:pivotX="12"
    android:pivotY="12"
    android:scaleX="1"
    android:scaleY="1">
    <path
      android:fillColor="#D8D8D8"
      android:fillType="evenOdd"
      android:pathData="M12,12m-8,0a8,8 0,1 1,16 0a8,8 0,1 1,-16 0"
      android:strokeWidth="1"
      android:strokeColor="#00000000" />
  </group>

  <!-- 3 -->
  <group
    android:name="translateGroup"
    android:translateX="1"
    android:translateY="1">
    <path
      android:fillColor="#D8D8D8"
      android:fillType="evenOdd"
      android:pathData="M28,4h16v16h-16z"
      android:strokeWidth="1"
      android:strokeColor="#00000000" />
  </group>

  <!-- 4 -->
  <group
    android:name="rotationGroup"
    android:pivotX="60"
    android:pivotY="14"
    android:rotation="0">
    <path
      android:fillColor="#D8D8D8"
      android:fillType="evenOdd"
      android:pathData="M60,4l8,16l-16,0z"
      android:strokeWidth="1"
      android:strokeColor="#00000000" />
  </group>
</vector>

Here you have:

  1. Added the vector with a virtual canvas of 72x24.
  2. Added a group named scaleGroup which draws a circle.
  3. Added a group named translateGroup which draws a square.
  4. Added a group named rotationGroup which draws a triangle image.

Next, create a few animations files in the anim folder.
Create a file named anim_rotate.xml and paste in the following XML:

<set xmlns:android="http://schemas.android.com/apk/res/android">
  <!-- 1 -->
  <objectAnimator
    android:duration="700"
    android:propertyName="rotation"
    android:valueFrom="0"
    android:valueTo="360"
    android:repeatCount="infinite"
    android:repeatMode="restart"
    android:valueType="floatType" />
</set>

Here you have added an ObjectAnimator in XML for the rotation property repeating a full rotation infinitely.

Create another file called anim_scale.xml and paste in the following XML:

<set xmlns:android="http://schemas.android.com/apk/res/android"
  android:shareInterpolator="true">
  <!-- 1 -->
  <objectAnimator
    android:duration="500"
    android:propertyName="scaleX"
    android:valueFrom="0"
    android:valueTo="1"
    android:repeatCount="infinite"
    android:repeatMode="reverse"
    android:valueType="floatType" />

  <!-- 2 -->
  <objectAnimator
    android:duration="500"
    android:propertyName="scaleY"
    android:valueFrom="0"
    android:valueTo="1"
    android:repeatCount="infinite"
    android:repeatMode="reverse"
    android:valueType="floatType" />
</set>

Here you have:

  1. Added an ObjectAnimator in XML for the scaleX property
  2. Added an ObjectAnimator in XML for the scaleY property

Both, repeating infinitely in reverse.

Create one more file called anim_translate.xml and paste in the following XML:

<set xmlns:android="http://schemas.android.com/apk/res/android">
  <!-- 1 -->
  <objectAnimator
    android:duration="700"
    android:propertyName="translateY"
    android:repeatCount="infinite"
    android:repeatMode="reverse"
    android:valueFrom="0"
    android:valueTo="12"
    android:valueType="floatType" />

  <!-- 1 -->
  <objectAnimator
    android:duration="500"
    android:propertyName="scaleY"
    android:repeatCount="infinite"
    android:repeatMode="reverse"
    android:valueFrom=".5"
    android:valueTo="1"
    android:valueType="floatType" />
</set>

Here you have:

  1. Added an ObjectAnimator in XML for the translateY property.
  2. Added an ObjectAnimator in XML for the scaleY property.

Again, both repeating infinitely in reverse.

The last piece of the puzzle is the vector drawable XML file. In the drawable folder, create a file named loading_animation.xml and copy the following XML:

<!-- 1 -->
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
  android:drawable="@drawable/ic_vd_loader">
  <!-- 2 -->
  <target
    android:name="scaleGroup"
    android:animation="@anim/anim_scale" />
  <!-- 3 -->
  <target
    android:name="rotationGroup"
    android:animation="@anim/anim_rotate" />
  <!-- 4 -->
  <target
    android:name="translateGroup"
    android:animation="@anim/anim_translate" />
</animated-vector>

Here you have:

  1. Added a animated-vector tag referencing to the vector drawable ic_vd_loader.xml.
  2. Added a target for the scaleGroup to use anim_scale.xml animation.
  3. Added a target for the rotationGroup to use anim_rotate.xml animation.
  4. Added a target for the translateGroup to use anim_translate.xml animation.

Almost done!

Now, open the layout/activity_splash.xml file and paste in this ImageView below the TextView:

  <ImageView
    android:id="@+id/loadingView"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_marginTop="24dp"
    app:srcCompat="@drawable/loading_animation"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/textView"/>
Note: Don't forget to replace the app:layout_constraintBottom_toBottomOf="parent" with app:layout_constraintBottom_toTopOf="@id/loadingView" on the TextView!

Finally, open the SplashActivity and add the following code just below the call to setContentView() in onCreate():

val animatable = loadingView.drawable as 
    android.graphics.drawable.Animatable
animatable.start()

Build and re-run the app and observe your awesome new loading animation!

Supporting Older API Versions

Vector drawables are supported back to API 21 by default but you can support them back to API 14 using Jetpack. This can be configured in your app level build.gradle file.

Add the following line to the defaultConfig of the app level build.gradle:

android {
   defaultConfig {
     // 1
     vectorDrawables.useSupportLibrary = true
   }
}

Here you have enabled the support library back to API 14.

To complete the process, anywhere you use VectorDrawable or AnimatedVectorDrawable you can replace them using the relevant VectorDrawableCompat and AnimatedVectorDrawableCompat classes. This, however, is not absolutely necessary for this project to support older API versions since you don't reference them in code.

Where to Go From Here?

Wow, that was a lot to chew on but you are now an expert on the vector image format in Android! [; In this tutorial, you did not see how you can clip paths and create masks with vector drawables. These are pretty powerful so you should definitely explore more about them.

Additionally, you covered a very simple animation with regard to AnimatedVectorDrawables and there are a lot more ways to make powerful animations such as using the ShapeShifter tool which will introduce you to create path morphing animations. You can also look further into the pathspec for anything you didn't get to try out here!

If you had trouble following along or just want to check it out, import the VectorDrawables-Finished project into Android Studio and run it! You can find this by using the Download Materials button at the top or bottom of this tutorial.

Please leave comments below with any questions and thanks for reading!