Tint VectorDrawable inside Drawable Resource xml
Asked Answered
K

1

16

i've had a drawable resource for a selectable Button/ImageView like this:

<selector>
<item android:state_selected="true">
    <layer-list>
        <item>
            <shape android:shape="oval">
                <solid android:color="@color/blue"/>
            </shape>
        </item>
        <item>
            <bitmap
                android:src="@drawable/ic_icon"
                android:tint="@color/white"/>

        </item>
    </layer-list>
</item>
<item>
    <layer-list>
        <item>
            <shape android:shape="oval">
                <solid android:color="@color/background_unselected"/>
            </shape>
        </item>
        <item>
            <bitmap
                android:src="@drawable/ic_icon"
                android:tint="@color/icon_unselected"/>
        </item>
    </layer-list>
</item>

as i've switched to use VectorDrawables the above declaration does not work because i cannot reference a VectorDrawable with a <bitmap> tag. But as far as i know that's the only way i can tint the icon.

I also cannot apply a Colorfilter in code as this would tint the whole drawable and not just the icon.

Any suggestions?

Kalsomine answered 20/6, 2017 at 9:57 Comment(0)
B
2

You can define colors as attributes and reference them in your SVG. Then can load the drawable styled by a theme.

Short example:

attributes.xml

<declare-styleable name="vectorColors">
    <attr name="primaryColor" format="color" />
    <attr name="secondaryColor" format="color" />
</declare-styleable>

ic_icon.xml

<path
    android:fillColor="?attr/primaryColor"
    android:pathData="...." />
<path
    android:fillColor="?attr/secondaryColor"
    android:pathData="...." />

styles.xml

<style name="svgColors">
    <item name="primaryColor">@color/someColor</item> 
    <!-- also can use #RRGGBB way -->
    <item name="secondaryColor">#ff0000</item>
</style>

Then load your theme and drawable:

Resources.Theme theme = getResources().newTheme();
theme.applyStyle(R.style.svgColors, false);
VectorDrawableCompat drawable = VectorDrawableCompat.create(getResources(), R.drawable.ic_icon, theme);
imageView.setImageDrawable(drawable);

In your specific selector you should replace

<item>
    <bitmap
        android:src="@drawable/ic_icon"
        android:tint="@color/white"/>
</item>

by <item android:drawable="@drawable/ic_icon">

Reference and full example

Boorman answered 14/7, 2017 at 23:8 Comment(4)
Nope. They don't. The solution is not valid.Belgravia
Well it is working through the code. My case was to change vector white paths to another color according to current theme. I did: 1. declared field <attr name="vectorWhite" format="reference|color"/> 2. added attr to my main theme <item name="vectorWhite">@color/colorForThisTheme</item> 3. called from code to get drawable knowing it's resource id by Drawable drawable = AppCompatResources.getDrawable(context, drawableId); 3. loaded image (at my case) by Glide.Fran
IMHO the key is to use drawable respecting current theme - I used AppCompatResources which itself finds what's theme now.Fran
This doesn't work, <bitmap> requires bitmap drawable, this crashes with XmlPullParserException "<bitmap> requires a valid 'src' attribute"Homogamy

© 2022 - 2024 — McMap. All rights reserved.