Android: как изменить android:fillcolor с помощью селектора в одном векторном рисуемом xml

Значки вкладок: мой текущий метод состоит в том, чтобы создать два файла (ic_list_selected_24dp.xml и ic_list_unselected_24dp.xml; они в основном одинаковы, но отличаются только android:fillColor='Color HEX CODE'), а затем создать селектор (selector_tabitem_list.xml), чтобы изменить отображаемый цвет, когда состояние изменено.

// @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>

Это как бы дублируется, потому что два чертежа одинаковы.

Селектор нельзя использовать в векторном рисовании.

<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>

, и android:fillColor="@color/state" либо.

// @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>

Есть ли способ использовать один рисунок и динамически менять его цвет? Использование жесткого шестнадцатеричного кода лучше?

Спасибо.


person cmingmai    schedule 08.05.2017    source источник
comment
Вы можете попробовать использовать android:drawableTint для представления   -  person VishnuSP    schedule 08.05.2017
comment
Спасибо за совет, но я использую этот чехол для значков вкладок. Все еще используете android:drawableTint? Кажется, он доступен в более высокой версии (›= 23). В чем разница между «Android: DrawableTint» и «Android: Tint»?   -  person cmingmai    schedule 08.05.2017
comment
Я нашел решение. Я добавил android:tint="@color/tab_state" в векторный тег.   -  person cmingmai    schedule 08.05.2017
comment
stackoverflow.com/questions/ 36741036/   -  person cmingmai    schedule 08.05.2017


Ответы (3)


Вот полный список шагов по использованию векторного актива в качестве тонированного значка в TabItem (который является частью библиотеки поддержки дизайна). Все части присутствуют в исходном вопросе и связанном ответе, но их легко пропустить.

  1. Создайте селектор. Обратите внимание, что он должен переключить цвет для state_selected (как указано в вопросе, но не в ответе, связанном с @cmingmai. Там указано только android:state_enabled, что не относится к вкладкам):

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>
  1. Настройте вектор, который можно рисовать, добавив android:tintMode и android:tint к векторному тегу. Вдобавок, чтобы тонировка работала с многократным, для fillColor контура необходимо установить значение 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>
  1. Используйте вектор, рисуемый в макете, или используйте его для создания вкладок в коде, как показано в разработчике руководство по вкладкам. Обратите внимание, что я также изменил цвет индикатора вкладки, чтобы он соответствовал цвету активного значка, чтобы следовать рекомендациям по дизайну материалов< /а>.

Соответствующая часть макета:

<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>
  1. Настройте build.gradle следующим образом, чтобы активировать поддержку векторов для старых версий Android (если она еще не была добавлена ​​ранее):

    android { defaultConfig { vectorDrawables.useSupportLibrary = true } }

person sunadorer    schedule 01.04.2018
comment
Убедитесь, что в вашем окончательном виджете нет android:tint. Это решение сработало для меня в ImageButton с app:srcCompat. - person BlackCath; 17.07.2018
comment
Вы действительно видите значки в tabLayout, не добавляя их программно? Я не могу заставить эти xml TabItems отображать значки - person galaxigirl; 08.06.2019
comment
@galaxigirl Да, мне не нужно было добавлять значки в другом месте. Извините, у меня больше нет доступа к проекту отсюда. Но я думаю, что активность добавила только адаптер/слушатель для обработки переключения контента при изменении вкладок. Не могу вспомнить, работал ли предварительный просмотр макета, но определенно работал во время работы. Вероятно, лучше всего, если вы застрянете, чтобы задать свой собственный вопрос. Может быть много разных вещей. например Ваша панель вкладок выглядит так, будто на ней есть место только для значка или текста? Может быть, цвет значка установлен на фон? Или дважды проверьте, как вы настроили drawable selector, если там есть требуемые состояния. - person sunadorer; 10.06.2019
comment
Кажется, это хорошо работает с androidX appcompat: 1.1.0. Просто установите цвет заливки в векторе, который можно нарисовать, на белый, а затем примените селектор android:tint, который можно нарисовать на самом изображении. Делая это очень гибким. - person Peterdk; 07.01.2020

Обновление до библиотеки поддержки 28.0.0+ (предположительно то же самое для androidx.. не проверял).

В библиотеке поддержки 28.0.0 использование xml-ресурса селектора цвета, похоже, теперь работает при использовании в качестве вектора android:fillColor.

На самом деле предыдущее решение (с использованием векторов android:tintMode, android:tint и белого цвета для android:fillColor) больше не работает для меня в библиотеке поддержки 28.0.0.

Протестировано на эмуляторах API 21 и 27.

person Jimmy Alexander    schedule 01.12.2018
comment
Я пробовал это с androidX appcompat: 1.1.0, и это не работает. Установка цвета заливки на белый, а затем добавление android:tint в изображение работает. - person Peterdk; 07.01.2020

Попробуйте заменить AppTheme в style.xml другим родителем, например:

имя стиля = "AppTheme" parent = "Theme.MaterialComponents.Light.DarkActionBar"

person Mitch    schedule 20.01.2019