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.

Here is Solutions:

We have many solutions to this problem, But we recommend you to use the first solution because it is tested & true solution that will 100% work for you.

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 🙁

Solution 2

You need to add vectorDrawables.useSupportLibrary = true to your build.gradle file:

// Gradle Plugin 2.0+  
 android {  
   defaultConfig {  
     vectorDrawables.useSupportLibrary = true  
    }  
 } 

You’ll note this new attribute only exists in the version 2.0 of the Gradle Plugin. If you are using Gradle 1.5 you’ll instead use:

// Gradle Plugin 1.5  
 android {  
   defaultConfig {  
     generatedDensities = []  
  }  

  // This is handled for you by the 2.0+ Gradle Plugin  
  aaptOptions {  
    additionalParameters "--no-version-vectors"  
  }  
 }  

You need to add srcCompat to your ImageView:

<ImageView  
  android:layout_width="wrap_content"  
  android:layout_height="wrap_content"  
  app:srcCompat="@drawable/ic_add" /> 

Note: Use and implement solution 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply