Android Selector Drawable не работает с атрибутами

Я использую attr для создания селектора, который можно нарисовать для моего проекта, чтобы после изменения цвета темы мне не пришлось вносить какие-либо изменения в файл для рисования. Я использую следующие библиотеки:

compile 'com.android.support:appcompat-v7:+'
compile 'com.android.support:cardview-v7:+'
compile 'com.android.support:design:22.2.0'

Вот исходный код для рисования:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="?attr/colorPrimary" android:state_enabled="true" android:state_window_focused="false"/>
    <item android:drawable="?attr/colorPrimaryDark" android:state_pressed="true"/>
    <item android:drawable="@android:color/darker_gray" android:state_enabled="false"/>
    <item android:drawable="?attr/colorPrimary"/>
</selector>

в этом же коде, если я заменяю атрибуты цветами, определенными в файле colors.xml, то же самое работает.

Образец для рисования с цветами:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@color/color_primary" android:state_enabled="true" android:state_window_focused="false"/>
    <item android:drawable="@color/color_primary_dark" android:state_pressed="true"/>
    <item android:drawable="@android:color/darker_gray" android:state_enabled="false"/>
    <item android:drawable="@color/color_primary"/>
</selector>

Заранее спасибо!

5 ответов

Решение

Наконец-то нашел проблему. В android [pre-lollipop] OS есть ошибка, которая не позволяет использовать attr в drawable. Вот ссылка на ошибку:

https://code.google.com/p/android/issues/detail?id=26251

Команда разработчиков Android выпустила исправление, но оно работает на Android L и выше. Чтобы обойти эту проблему, обратитесь к следующему решению:

Как ссылаться на атрибуты стиля из прорисовки?

Я столкнулся с той же проблемой, и по состоянию на 2019 год она не была решена, поэтому вы не можете ссылаться на атрибут в селекторе как на доступный для рисования. Я поделюсь своим решением проблемы, так как я не вижу его здесь. Я нашел это в последнем комментарии отчета об ошибке, на который также ссылается mudit в своем ответе.

Обходной путь в основном состоит в создании доступного для рисования ресурса, который будет ссылаться на значение атрибута.

Чтобы проиллюстрировать ваш случай, решение будет вместо:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="?attr/colorPrimary" android:state_enabled="true" android:state_window_focused="false"/>
    <item android:drawable="?attr/colorPrimaryDark" android:state_pressed="true"/>
    <item android:drawable="@android:color/darker_gray" android:state_enabled="false"/>
    <item android:drawable="?attr/colorPrimary"/>
</selector>

вы бы заменили?attr/* на ресурс с возможностью рисования:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/colorPrimaryDrawable" android:state_enabled="true" android:state_window_focused="false"/>
    <item android:drawable="@drawable/colorPrimaryDarkDrawable" android:state_pressed="true"/>
    <item android:drawable="@android:color/darker_gray" android:state_enabled="false"/>
    <item android:drawable="@drawable/colorPrimaryDrawable"/>
</selector>

Чертежи будут определены как:

drawable / colorPrimaryDrawable

<shape xmlns:android="http://schemas.android.com/apk/res/android"android:shape="rectangle">
    <solid android:color="?attr/colorPrimary" />
</shape>

вытяжка /colorPrimaryDarkDrawable

<shape xmlns:android="http://schemas.android.com/apk/res/android"android:shape="rectangle">
    <solid android:color="?attr/colorPrimaryDark" />
</shape>

Надеюсь, это поможет!!

Я не знаю, относится ли это к вам, но я боролся с тем же и думаю, что нашел обходной путь (вроде). Прямое использование? Attr/ не работает (работает на API 21 и выше, но даже тогда не работает с селекторами цвета (только с рисованными объектами).

Так что я сделал это так (приведу свой пример). Создать атрибут в attr.xml

<attr name="nav_item_color_selector" format="reference|color"/>

Затем во всех темах, которые вы используете, добавьте атрибут следующим образом (например, Light Theme):

<item name="nav_item_color_selector">@color/text_color_selector_light</item>

или для темной темы (по умолчанию):

<item name="nav_item_color_selector">@color/text_color_selector</item>

Теперь мой text_color_selector.xml (оба) выглядит так:

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

и когда я хочу их использовать, например, при тонировании своего пользовательского изображения, я использую:

    <com.yourdomain.yourpackage.NavDrawerIcon
    android:layout_width="24dp"
    android:layout_height="24dp"
    android:layout_gravity="center_vertical"
    android:src="@mipmap/ic_launcher"
    android:id="@+id/nav_item_icon"
    android:layout_margin="24dp"
    android:tint = "?attr/nav_item_color_selector"
    android:tintMode="src_atop"/>

Вы также можете повторно получить его программно, используя TypedValue, например:

    TypedValue typedValue = new TypedValue();
    Resources.Theme theme = context.getTheme();
    theme.resolveAttribute(R.attr.nav_item_color_selector, typedValue, true);
    XmlResourceParser parser = viewGroup.getContext().getResources().getXml(typedValue.resourceId);
    try {
        ColorStateList sl = ColorStateList.createFromXml(viewGroup.getContext().getResources(), parser);
        viewHolder.textView.setTextColor(sl);

    } catch (Exception e) {  }

Надеюсь, это поможет:-)

Я столкнулся с аналогичной проблемой при использовании атрибутов для цвета в селекторе с возможностью рисования.

Я решил это, создав селектор цвета вместо селектора с возможностью рисования . По сути, создайте новый ресурс с типом ресурса в качестве цвета, который будет вашим селектором цвета. Здесь, в отличие от селекторов с возможностью рисования, вы можете без проблем использовать свои атрибуты:

      <selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="?colorBackgroundDisabled" android:state_enabled="false" />
    <item android:color="?colorBackground" />
</selector>

^ Я назвал это selector_background.

Затем вы можете использовать этот селектор:

      <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/selector_background"/>

Вместо того, чтобы поставить "?" Измените это на "@"

Другие вопросы по тегам