Vector Graphics on Android
- Getting Started
- What is a Vector Drawable
- Vector vs. Raster Graphics
- Creating Assets Before Vector Drawables
- When to Apply Vector Drawables
- Creating a Vector Drawable by Hand
- Fill and Stroke
- Drawing Commands
- Move to (M)
- Line to (L)
- Bezier Curve to (C)
- Closing a Path (Z)
- Uppercase vs. Lowercase Commands: Using Relative Path Commands
- Creating a VectorDrawable in Android Asset Studio
- Adding Vector Assets to UI Components
- Tinting a VectorDrawable
- Scaling a VectorDrawable Programmatically
- Animated Vector Drawables
- Creating a Loader Using AnimatedVectorDrawable
- Supporting Older API Versions
- Where to Go From Here?
In this tutorial, you will work with scalable vector graphics (SVG) on Android to build an application that creates shareable images using baby-faced emojis that can be scaled and repositioned on a background image.
Vector graphics are an extremely powerful image format that both reduce your apk’s size and provide a more dynamic visual appearance that scales across the various screen densities within the Android ecosystem. You will learn about this format through the standard SVG pathspec commands available which will help you to understand the theory behind drawing them. You will also learn by using the related APIs in Android.
In addition, you will learn how to apply them to widgets and about the support Android provides for SVGs on lower API levels. Finally, you will wrap up the tutorial by learning how to animate a vector drawable to create a cool loading animation on the splash screen of the app.
Download the project materials using the Download Materials button at the top or bottom of this article. Then, import the project into Android Studio to get started.
Build and run the app. The first screen you’ll see is one where you can place baby-faced emojis on a background. Try saving one.
By clicking History in the toolbar, you can view your creation.
Great! Time to keep going.
What is a Vector Drawable
VectorDrawables are the SVG equivalent on Android. They are defined in XML using resource files and can be dynamically altered at runtime. The SVG format is an open standard image format defined by the World Wide Web Consortium (W3C) for creating scalable, interactive and animatable images through XML. While the API on Android is not a one-to-one match with the SVG format provided by the web, it offers the ability to draw individual paths, groups of paths, and create clipping masks to compose complex graphical assets for your applications. You can think of this process as drawing an image on paper using a pen or pencil.
Why do you need this type of image format though if Android supports the ability to serve different resources using the density resource buckets?
Well, to understand more you can compare with the older format, raster images.
Vector vs. Raster Graphics
Raster image formats (.BMP, .TIF, .JPG, .GIF, and .PNG) are what you probably have the most experience with in the past. These are grids of pixels that are a fixed size only containing color information. You can imagine how limiting this is compared to the vector format which describes the images as a series of points and paths composing shapes on an arbitrary grid size, which can also be colored dynamically. Raster images can be colored as well but the real difference comes when scaling them up. They become pixelated as they get larger and they lose their sharpness when compared to SVG. Look at the example below to see the difference when scaling.
Creating Assets Before Vector Drawables
In Android Studio, creating assets before vector drawables required working with designers to create a baseline image at a fixed size and then duplicate that image scaling it up for the different screen density buckets.
For example, to draw a share icon at 24×24 density independent pixels (dp) a designer would create a canvas at this pixel size and then draw the artwork within it. This would be the baseline graphic provided for the mdpi (160dpi) screen devices. Then the designer would need to create an additional canvas at 36×36 (1.5x for hdpi), 48×48 (2x for xhdpi), 72×72 (3x for xxhdpi) and 96×96 (4x for xxxhdpi) and scale or redraw the artwork to fit these bounds.
This was, however, only necessary for icons that Android Studio didn’t provide by default in its icon collection within Asset Studio (more on this in a bit). As you can infer, this process of providing assets for every screen density would bloat your app taking up more space on your user’s devices and increase the download time from the Play Store. This isn’t the best experience but it cannot always be avoided with Vector drawables as they are no silver bullet.
When to Apply Vector Drawables
Vector drawables can be applied in various places within your Android application where raster graphics used to be the default. For simple assets across your application like icons, they are the perfect solution to providing rich imagery scalable across different densities with minimal apk bloat. They can also be used to replace illustrations throughout your application. They cannot, however, be used to replace things like photos. As mentioned before, VectorDrawables uses XML to describe the paths, shapes and fills for an asset which gets inflated at runtime, so complex shapes can take some time to render on screen and take a performance hit on your application if they have many paths to draw.
Enough theory and information already. How do you create these
Creating a Vector Drawable by Hand
Creating a vector by hand isn’t all that complex for simple graphics so that is what you will start with here. As previously mentioned, paths are drawn using a series of commands from the SVG pathspec much like drawing with a pencil on paper.
Consider creating the following asset:
You can accomplish this through Android by specifying it as a vector drawable.
Start by creating a file named ic_temp.xml in the res ‣ drawable folder. Then, paste the following XML into the file:
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp" android:height="24dp" android:viewportWidth="24.0" android:viewportHeight="24.0"> <!-- Groups and paths will go here--> </vector>
Here you have defined a vector drawable with a virtual canvas of 24×24 pixels and a physical asset size of 24x24dp