Android Tutorial: Simple, Scalable, Vector Graphics and Animations

This article is accompanied by a video tutorial on “the youtubes”. Consider checking it out for a more direct and hands-on learning experience.

Ryan Michael Kay
8 min readMay 6, 2019

This article covers:

  • How to find free public domain/open license images to avoid starting from scratch (for those of us who do not have the time or artistic inclination to create them from nothing)
  • How to create scalable Vector graphics out of these images, using free tools and resources
  • How to create graphic assets in Android Studio from these vector graphics
  • Finally, how to create simple but effective animations, without requiring you to learn 15 different animation APIs.

The end result will be vector drawables and animations which scale to almost any screen type without loss of detail; without needing you to bloat your app with image resources for different resolutions.

Preliminaries:

Before we get to the practical stuff, it is worth understanding what vector graphics are (such as .svg), and how they are different from raster graphics formats (such bmp, png, jpeg…).

The key difference is that formats like bitmap (among other raster graphic formats), are collections of bits, which ultimately represent pixels which are drawn on screen.

Imagine dividing up whatever screen you are looking at into a two dimensional grid with an X and Y axis. Supposing the bounds of the grid are 1920x1080 pixels, one could store every pixel in an array (or some other collection). When it is time to draw the image, the computer iterates through the array, drawing each pixel on the screen at the appropriate coordinate, with the appropriate colour data.

If one were to try and display a raster graphic with a resolution of 240x135 pixels, and fit it to the entire screen, the image would necessarily become blocky.

Hopefully that made sense, but even if it did not, here is what it means: Raster graphics do not scale well, and if you wish to show them with a variety of different screen sizes and densities, you probably need to provide different copies of the same image, with different resolutions to account for this.

Raster graphics are resolution dependent.

Enter The Vector

A vector drawable represents an image as a series of coordinates (or points), along with other data necessary to render the image. The most common vector drawable format, Scalable Vector Graphics, or .svg, has options to specify colours, lines, curves, paths, gradients, and more.

Instead of specifying a finite collection of pixels in an array, the file contains path coordinates (and other information) which tell the device where and what you want to draw on an 2d grid (or 3d even). An easy way to visual this, is to imagine that someone gave you a series of dots on a piece of paper, and asks you to trace between them with a pencil, then fill the shape in with a coloured marker.

modern computers happen to be really damn good at math, so calculating how to draw a giant collection of points on whatever screen size and density is quite easy for them. The result is that you can have a single file, which can be rendered on just about any resolution (within reason).

Vector graphics are resolution independent.

Important Note:

While having a single file is great, it is entirely possible to have vector image files which are insanely large. As a general rule, highly detailed images such as photos of things in nature (like people, landscapes, cities) posses far to many points (sets of coordinates) to feasibly be used in vector format.

More cartoon-like images and animations are perfect to be used as vector images, as they tend to contain more consistent shapes, colours, and so on. However, some vector image editing tools allow a person to simplify high detail images into reasonably sized files.

1. Finding/Making Good Quality, Free Images

Note: It looks much better in the App with the Space background.

In this tutorial, we will create three separate .svg files which will form each frame of the Rocket animation from JetpackNotes. Note that the above image is a raster based GIF animation; we use proper vector drawable for the animation within the application itself.

No Need To Start From Scratch

If you are reading this article and happen to be a graphic designer, then you can probably skip this section. Assuming that you want to have good quality graphics and animations in your application (which you should), I will show you my main resource for finding images which can serve as a good starting point for code monkeys like me.

The first thing I did to create this animation, was to visit openclipart.org and search “Rocket.”

This website maintains a large collection of images which are free to be edited and reused for any purpose. Now, I did not pick any old image, but went with something which vaguely fits the Material Design aesthetic which is popular for Android applications:

I then used the open source graphic editing tool called GIMP to modify the image to fit the application. Since I already chose a particular colour scheme for the application, I made sure to match that colour scheme for the edited image.

What Is An Animation?

The easiest way to understand what an animation is, is to think of it as a series of images being drawn one after another on the screen. Since I wanted to indicate some kind of motion for the Rocket, I created three different versions of the image with different angles for the ship, and shapes for combustion of the thrusters:

Working With SVG For Free

GIMP is a great tool for the price, but it has only very limited functionality for working with vector graphics. After I created each image, I outputted them to a reasonably high resolution .png file.

Many of you reading this will have access to powerful tools such as Adobe Illustrator. I cannot provide instructions for creating SVGs from this tool, as I use a free and open source tool called Inkscape for working with Vector graphics.

For detailed instructions on creating .svg files from .png files in Inkscape, watch the accompanying video.

Before proceeding, using whatever tools you prefer, ensure that you have created an .svg image file which we will import to Android Studio in a moment.

2. SVG in Android Studio

However you choose to create .svg files for your application, it is time to import them using Android Studio. In recent versions of AS, you will find a tool called Vector Asset Studio, which does two very useful things for us:

  1. Allows us to convert .svg files in to vector drawables, which plain .xml files.
  2. Allows us to access, and create vector drawables from all of the wonderful material design icons which Google makes available to us developers.

Let us create a Vector Asset out of the .svg files, which will prepare it for use in our applications:

In Android Studio, right click on the res/drawable folder -> New -> Vector Asset. As a quick tip, if you want to create some vector assets out of pre-made icons, select the “clip art” button to open a dialogue window and search the available pre-made icons.

Since we are supplying the .svg files, select Local file -> locate the path to the .svg. Unless it suits your needs, leave the size and opacity fields at default, and select Next -> Finish.

Important Note:

If you want your application to be capable of supporting Android Platform API less than 21, then the Asset Studio tool will likely create raster graphics in addition to the .xml asset. This is because support for vectors is not available on older API versions.

3. Creating The Animation

We can now refer to these generated files just like any other drawable on the android platform. If your goal in reading this was to simply make nice, scalable vector drawables, then your mission has been accomplished. To finish off, I will show you how to create animations out of a series of vector assets, which do not require monkeying with any confusing animation APIs.

We will create an animation list.

To create an animation list, create a new .xml resource in res/drawable. I have chosen to call mine rocket_loop.xml. The idea is very simple:

  • In the animation-list .xml element/tag, set android:oneshot=”false” to allow continuous looping (if appropriate)
  • Add an item element for each frame of the animation. Remember to point it to the vector drawables generated by Vector Asset studio; not your original .svg files.
  • android:duration=”” specifies how long each frame is shown in milliseconds. I recommend tweaking this once you actually test deploy the animation.

rocket_loop.xml:

<?xml version=”1.0" encoding=”utf-8"?><animation-list xmlns:android=”http://schemas.android.com/apk/res/android"android:oneshot=”false”><item android:drawable=”@drawable/im_rocket_one” android:duration=”200" /><item android:drawable=”@drawable/im_rocket_two” android:duration=”200" /><item android:drawable=”@drawable/im_rocket_three” android:duration=”200" /></animation-list>

Note that you may also use an animation-list with raster graphics like .png or .bmp. I do exactly that for the high-detail space background animation which sits behind the low detail vector animation in JetpackNotes.

Adding The Animation List To The Layout

In whichever Layout/View you wish to display the Animation, set its android:src=”” attribute to the animation list .xml file. If necessary, you may tint, resize, set margins, and so forth to get the correct look and dimensions.

...
<ImageView android:id="@+id/imv_note_detail_animation" android:layout_width="0dp" android:layout_height="0dp" android:src="@drawable/rocket_loop" android:alpha=".86" android:layout_marginStart="16dp" android:layout_marginTop="16dp" android:layout_marginEnd="16dp" android:layout_marginBottom="16dp" app:layout_constraintBottom_toTopOf="@+id/gdl_detail_middle" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/tlb_detail_fragment" />
...

Starting The Animation

In your Activity, Fragment, or whatever else has a hook to the View with the AnimationDrawable, at runtime, you will need to:

  • Get ahold of the View’s drawable, by property (Kotlin) or getter (Java)
  • Cast the drawable to an AnimationDrawable
  • Call .start() function on the AnimationDrawable
private fun showLoadingState() {        (imv_note_detail_satellite.drawable as AnimationDrawable).start()    }

Adding Fade Effect For Smoother Transitions

Although I do not use any fade for the Rocket Animation, I do set a fade for the looping Space background images in the App. I created a simple extension function to reduce the boilerplate calls to set the fade, which looks like this:

internal fun AnimationDrawable.startWithFade(){    this.setEnterFadeDuration(1000)    
this.setExitFadeDuration(1000)
this.start()}

Starting this animation within onStart() for the Fragment becomes:


//...
(frag_note_detail.background as AnimationDrawable).startWithFade()
//...

If You Learned Something…

Learn More

Application Programming Fundamentals with Kotlin and Android

Social

https://www.instagram.com/wiseassbrand/
https://www.facebook.com/wiseassblog/
https://twitter.com/wiseass301
http://wiseassblog.com/

Donate

https://www.paypal.me/ryanmkay

--

--

Ryan Michael Kay

Self-taught software developer & student of computer science.