How to properly use backwards compatible Vector Drawable with the latest Android Support Library?

Vector drawable has been added to Support Library not so long time ago and there were a lot of changes in the API since then: Gradle flags, initializer blocks, selectors, custom XML attributes etc. The question is - how to properly use it now (support lib v25) in these cases:

  • ImageView
  • TextView drawable
  • Menu icon
  • Notification icon

XML and programmatically.


Solution 1:

Add the latest support lib to your app's build.gradle dependencies:

compile 'com.android.support:appcompat-v7:26.0.2'

and add the following line in the same file:

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

Import vector image through Vector Asset Studio.

That's all, you are ready to go!


ImageView

XML

Use app:srcCompat attribute instead of android:src:

<ImageView
    ...
    app:srcCompat="@drawable/your_vector" 
    ... />

Programmatically

Directly from resource id:

imageView.setImageResource(R.drawable.your_drawable);

Set as Drawable object (e.g. for tinting):

Drawable vectorDrawable 
                = AppCompatResources.getDrawable(context, R.drawable.your_vector);
imageView.setImageDrawable(vectorDrawable);

And if you want to set tint:

DrawableCompat.setTint
             (vectorDrawable, ContextCompat.getColor(context, R.color.your_color));

TextView drawable

XML

There is no simple solution: XML attribute android:drawableTop(Bottom etc) can't handle vector images on pre-Lollipop. One solution is to add initializer block to activity and wrap vector into another XML drawable. Second - to define a custom TextView.

Programmatically

Setting resource directly doesn't work, you have to use Drawable object. Get it the same way as for ImageView and set it with the appropriate method:

textView.setCompoundDrawablesWithIntrinsicBounds(vectorDrawable, null, null, null);

Menu icon

There is nothing special:

<item
    ...
    android:icon="@drawable/your_vector"
    ... />

menuItem.setIcon(R.drawable.your_vector);

Notifications:

It's impossible, you have to use PNGs :(