Illustration by Virginia Poltrack

Using vector assets in Android apps

Nick Butcher
Dec 11, 2018 · 6 min read

AndroidX First

From Lollipop onward, you can use VectorDrawables anywhere you would use other drawable types (referring to them using the standard @drawable/foo syntax) but I would instead recommend to always use the AndroidX implementation. This obviously increases the range of platforms you can use them on but more than this, it enables backporting of features and bug fixes to older platforms too. For example, using VectorDrawableCompat from AndroidX enables:

  • Gradient & ColorStateList fills/strokes (added to platform impl in API 24)
  • Bug fixes
(VDC == VectorDrawableCompat)

How?

To use the AndroidX vector support, there are 2 things that you need to do:

1. Enable Support

You need to opt in to AndroidX vector support in your app’s build.gradle:

android {
defaultConfig {
vectorDrawables.useSupportLibrary = true
}
}

2. Load with AndroidX

When loading drawables you need to use methods from AndroidX which provide the backported vector support. The entry point for this is to always load drawables with AppCompatResources.getDrawable. While there are a number of ways to load drawables (because reasons), you must use AppCompatResources if you want to use compat vectors. If you fail to do this, then you won’t hook into the AndroidX code path and your app might crash when trying to use any features not supported by the platform you’re running on.

  • Do: app:srcCompat
  • Do: app:buttonCompat
  • Do: app:drawableStartCompat app:drawableTopCompat etc.

In Practice

These requirements effect the way you might create a layout or access resources. Here are some practical considerations.

Views without compat attributes

Unfortunately there are a number of places you may want to specify drawables on views that don’t offer compat attributes (e.g. there’s no indeterminateDrawableCompat attribute for ProgressBars) i.e. anything not listed above. It’s still possible to use AndroidX vectors, but you’ll need to do this from code:

Nested drawables

Some drawable types are nestable e.g. StateListDrawables, InsetDrawables or LayerDrawables contain other child drawables. The AndroidX support works by explicitly knowing how to inflate <vector> elements (also animated-vectors and animated-selectors, but we’ll focus on static vectors today). When you call AppCompatResources.getDrawable, it peeks at the resource with the given id and if it is a vector (i.e. the root element is <vector>), it manually inflates it for you. Otherwise, it hands it off to the platform to inflate — when doing so, there’s no way for AndroidX to re-insert itself back into the process. That means that if you have an InsetDrawable containing a vector and ask AppCompatResources to load it for you, it will see the <inset> tag, shrug, and hand it to the platform to load. It therefore will not get a chance to load the nested<vector> so this will either fail (on API <21) or just fall back to the platform support.

Credit for this genius hack: https://twitter.com/alexjlockwood/status/1029088247131996160

Out of process loading

Sometime you need to provide drawables in places where you don’t control when or how they are loaded. For example: notifications, homescreen widgets or some assets specified in your theme (e.g. setting android:windowBackground which is loaded by the platform when creating a preview window). In these cases you aren’t responsible for loading the drawable so there’s no opportunity to integrate AndroidX support and you cannot use vectors pre-API 21 😞.

res/
drawable-xxhdpi/
foo.png <-- raster
drawable-anydpi-v21/
foo.xml <-- vector
drawable-anydpi-v24/
foo.xml <-- vector with fancy features

X Marks the Spot

Hopefully this article has highlighted the benefits of using the AndroidX vector support and some limitations that you need to be aware of. Using the AndroidX support both enables vectors on more platform versions and backports functionality but also sets you up to receive any future updates.

Android Developers

The official Android Developers publication on Medium

Thanks to Doris Liu, Florina Muntenescu, and Chris Banes.

Nick Butcher

Written by

Android designer + developer @ Google

Android Developers

The official Android Developers publication on Medium