Theme attributes not working correctly with VectorDrawable

Viewed 590

I work on application which supports multi themes, dark and light, with min sdk version 21. I found out that it's possible to use theme attribute (e.g. ?attr/logo_color) inside VectorDrawable.

So for example, If I set theme attribute to fill color of desired path

<vector ...>
<path 
     android:pathData="..."
     android:fillColor="?attr/logo_color"/>
</vector>

or set theme attribute to tint whole vector

<vector android:tint="?attr/logo_color">
...
</vector>

I run the app (light theme), it sets color correctly, but when I change theme Activity.setTheme() (light to dark), color is not changed. Color is always 'cached' to previous theme's color. Interesting is that this doesn't work on lollipop and marshmallow, however on Android 10 it changes correctly.

On the other hand hand if I set android:tint="" color inside ImageView

<ImageView
            ...
            app:srcCompat="@drawable/ic_logo"
            android:tint="?attr/logo_colo"/>

It works with all versions but it of course change color of whole drawable.

Is it any bug or is it possible to use theme attributes inside VectorDrawable on lower apis with run time theme change?

1 Answers

Was facing the same issue, what I did was the following things

  1. In the build.gradle file (app level), set the following (Suggesting this point since you have not mentioned what is the minSdk you are supporting)
android {
    defaultConfig {
        vectorDrawables.useSupportLibrary = true
    }
}
  1. If you are setting such drawables to any kind of views during run time or dynamically then

Instead of this (which is now deprecated)

context.getResources().getDrawable(/*Your resource id*/)

Use this

ContextCompat.getDrawable(context, /*Your resource id*/)

Explanation: What the ContextCompat class does is make sure that the drawable you get is complying to whatever theme is currently being used in your app (Android 5.0+) If you support even below that, then you can use a ContextThemeWrapper to wrap your current context and apply a specific theme to the drawable and then use it whenever you like

Good things to read

Jorge Castillo's Article about ContextThemeWrapper

Related