Android: How to change android:fillcolor with selector in one Vector Drawable xml

android, android-selector, android-tablayout, android-tabs, android-vectordrawable

Solution

Here is the complete list of steps to use a vector asset as tinted icon in a TabItem (which is part of the support design lib). All parts are present in the original question and linked answer, but are easy to miss.

- Create the selector. Note that it has to switch the color for `state_selected` (as included in the question, but not in the answer linked by @cmingmai. There it only states android:state_enabled which is not relevant for tabs):

res/color/selector_navigation.xml:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_selected="false" android:color="@android:color/black" />
    <item android:state_selected="true" android:color="@android:color/white" />
</selector>

- Adjust the vector drawable by adding `android:tintMode` and `android:tint` to the vector tag. In addition for the tinting to work with multiply, the fillColor of the path needs to be set to white!

res/drawable/ic_tab_list:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:height="24dp"
        android:width="24dp"
        android:viewportHeight="24.0"
        android:viewportWidth="24.0"
        android:tintMode="multiply"
        android:tint="@color/selector_navigation">
    <path
        android:fillColor="@android:color/white"
        android:pathData="..." />
</vector>

- Use vector drawable in Layout – or use to create the tabs in code as shown in the developer guide on Tabs. Note that I also modified the tab indicator color to match the active icon color to follow the material design guidelines.

Relevant part of the layout:

<android.support.design.widget.TabLayout
    android:id="@+id/tabs"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:tabIndicatorColor="@android:color/white">

    <android.support.design.widget.TabItem
        android:id="@+id/tabItem"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:icon="@drawable/ic_tab_list" />
    <!-- More Tabs -->
</android.support.design.widget.TabLayout>

Adjust build.gradle with following to activate vector support for old Android versions (in case it was not already previously added):

android { defaultConfig { vectorDrawables.useSupportLibrary = true } }

Problem

Tab Icons: My current method is to create two files (ic_list_selected_24dp.xml and ic_list_unselected_24dp.xml; they are basically the same but only the `android:fillColor='Color HEX CODE'` are different), and then create a selector (selector_tabitem_list.xml) to change the drawable color when the state is changed. ``` // @drawable/selector_tabitem_list.xml <selector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <item android:drawable="@drawable/ic_list_selected_24dp" android:state_selected="true" /> <item android:drawable="@drawable/ic_list_unselected_24dp" android:state_selected="false" /> </selector> ``` It's kind of duplicated because two drawables are the same. Selector cannot be used in vector drawable. ``` <vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp" android:height="24dp" android:viewportWidth="24.0" android:viewportHeight="24.0"> <path android:fillColor="@drawable/selector" android:pathData="M19,3...." </vector> ``` -- ``` // @drawable/selector <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_selected="true"> <color android:color="@color/itemSelected" /> </item> <item android:state_selected="false"> <color android:color="@color/itemUnselected" /> </item> </selector> ``` , and `android:fillColor="@color/state"` either. ``` // @color/state <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:color="@android:color/white" android:state_selected="true" /> <item android:color="@android:color/black" android:state_selected="false" /> </selector> ``` Is there any way to use one drawable and change its color dynamically? Using hard hex code is better? Thanks.

Original source

Related problems