Селектор цвета фона TextView

121

Я пытаюсь изменить цвет фона TextViewвиджета Android, когда пользователь прикасается к нему. Для этой цели я создал селектор, который хранится res/color/selector.xmlпримерно так:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:state_pressed="true"
        android:color="@color/semitransparent_white"
        />
    <item
        android:color="@color/transparent"
        />
</selector>

clickableАтрибут TextViewявляется true, в том случае, представляющие интерес.

Когда я назначаю этот селектор TextViewas android:background="@color/selector", во время выполнения я получаю следующее исключение:

ОШИБКА / AndroidRuntime (13130): вызвано: org.xmlpull.v1.XmlPullParserException: строка двоичного файла XML № 6: тег требует атрибута 'drawable' или дочернего тега, определяющего возможность рисования

Когда я меняю атрибут на drawable, он работает, но результат выглядит совершенно неверным, потому что идентификаторы интерпретируются как ссылки на изображения, а не как ссылки на цвета (как предполагает «drawable»).

Что меня смущает, так это то, что я могу установить ссылку на цвет, например "@ color / black", как атрибут фона напрямую. Это работает, как ожидалось. Использование селекторов не работает.

Я также могу textColorбез проблем использовать селектор .

Как правильно применить селектор фонового цвета к TextViewв Android?

digitalbreed
источник
Цвет можно интерпретировать как доступный для рисования. В чем именно неверный результат?
Romain Guy
Вместо этого в качестве фона отображается не цвет, а изображение из моих доступных ресурсов.
digitalbreed
2
Вышеупомянутое должно работать, если вы используете android: drawable, а не android: color - по крайней мере, в этом случае у меня работает: android: drawable = "@ color / my_custom_color". Мои цвета определены в values ​​/ colors.xml
AgentKnopf

Ответы:

226

Проблема здесь в том, что вы не можете определить цвет фона с помощью селектора цвета, вам нужен селектор с возможностью рисования . Итак, необходимые изменения будут выглядеть так:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:state_pressed="true"
        android:drawable="@drawable/selected_state" />
</selector>

Вам также необходимо переместить этот ресурс в drawableкаталог, где он будет иметь больше смысла, поскольку сам по себе не является селектором цвета.

Тогда вам нужно будет создать такой res/drawable/selected_state.xmlфайл:

<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" 
    android:shape="rectangle">
    <solid android:color="@color/semitransparent_white" />
</shape>

и, наконец, вы бы использовали его так:

android:background="@drawable/selector"

Примечание : причина, по которой OP рисовал ресурс изображения, вероятно, связана с тем, что он пытался просто сослаться на свой ресурс, который все еще находился в каталоге цветов, но использовал, @drawableпоэтому он столкнулся с конфликтом идентификаторов, выбрав неправильный ресурс.

Надеюсь, это все еще может помочь кому-то, даже если OP, я надеюсь, решил свою проблему к настоящему времени.

Бенуа Мартин
источник
1
Спасибо, Бенуа. Проблема была решена (признаюсь, не могу вспомнить, как именно я это сделал в итоге) и проект был успешно завершен. Я ценю, что вы вернулись сюда, чтобы написать и помочь людям, столкнувшимся с той же проблемой в будущем, отличный дух!
digitalbreed
Я не могу заставить это работать. Я пытаюсь применить его к кнопке, и он устанавливает для фона цвет селектора по умолчанию, но он не меняется на форму, определенную в state_pressed. Что я мог упустить? Я могу задать новый вопрос, на всякий случай, если вы укажете мне правильное направление.
Мараг,
@Maragues трудно сказать, не увидев кода. Я бы порекомендовал вам открыть новый вопрос и опубликовать соответствующий код, чтобы мы могли понять, что может быть не так. Вы также можете добавить комментарий к этому сообщению со ссылкой на ваш новый пост.
Бенуа Мартин
9
Почему бы вместо этого просто не использовать "drawable =" @ color / your_color "прямо в элементах селектора? Вам не нужно определять какие-либо фигуры или какие-либо другие файлы вообще, просто укажите свои определения цвета в values ​​/ colors.xml (это всегда хорошо не жестко кодировать цвета)
javaxian
Не работает. Он показывает мне цвет, отличный от того, который я объявил в форме xml.
Эр-Рохит Шарма
122

Решение Бенуа работает, но вам действительно не нужно нести накладные расходы, чтобы нарисовать форму. Поскольку цвета можно рисовать, просто определите цвет в файле /res/values/colors.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="semitransparent_white">#77ffffff</color>
</resources>

А затем используйте как таковой в своем селекторе:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:state_pressed="true"
        android:drawable="@color/semitransparent_white" />
</selector>
azdev
источник
По какой-то причине ваше решение отображает не цвет, а случайное изображение из моей папки с доступными ресурсами. Я попытался очистить проект / исправить свойства / повторно сохранить / снова открыть затмение, это кажется действительно странным, но безрезультатно. Weird.
Yahel
@Yahel Вы, возможно, назвали ресурс для рисования цветом так же, как и фактический файл для рисования?
Jona
@Jona: Нет, но объект для рисования был назван background_application, а цвет для рисования - background_white_transparent. У обоих была предыстория ... Я видел в другом потоке, что то же самое происходит с другими, поэтому я зарегистрировал это как одну из многочисленных ошибок Android и обновил весь свой макет, чтобы исправить это.
Yahel
@Yahel Ммм ... Ну, я вижу эту проблему, но в моем случае не те имена файлов ... Ознакомьтесь с моими вопросами здесь stackoverflow.com/questions/9004744/…
Jona
не удалось заставить его работать, ответ от Бенуа Мартина работал нормально.
Эммануэль Тузери,
83

Еще более простое решение вышеуказанного:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true">
        <color android:color="@color/semitransparent_white" />
    </item>
    <item>
        <color android:color="@color/transparent" />
    </item>
</selector>

Сохраните это в папке с возможностью рисования, и все готово.

Джейсон Робинсон
источник
1
Возможно, это работает, но официально не поддерживается (Android Studio рассматривает это как ошибку).
Blackhex
@Blackhex Странно. У меня отлично работает в Eclipse. Вероятно, это ошибка Lint, и если это так, вы можете отключить или проигнорировать ее.
Джейсон Робинсон,
6
Это то, что я считаю решением.
Lay González
<item android:state_pressed="true" android:color="@color/vantablack"/>семантически идентично<item android:state_pressed="true"><color android:color="@color/vantablack"/></item>
samis
16

Даже это работает.

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

Я добавил android:drawableатрибут к каждому элементу, и их значения - цвета.

Кстати, а почему говорят, что colorэто один из атрибутов selector? Они не пишут, что android:drawableтребуется.

Ресурс списка состояний цвета

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
    <item
        android:color="hex_color"
        android:state_pressed=["true" | "false"]
        android:state_focused=["true" | "false"]
        android:state_selected=["true" | "false"]
        android:state_checkable=["true" | "false"]
        android:state_checked=["true" | "false"]
        android:state_enabled=["true" | "false"]
        android:state_window_focused=["true" | "false"] />
</selector>
Максим Дмитриев
источник
Атрибут цвета работает, когда вы устанавливаете цвета текстового просмотра, но не с фоном, так как на самом деле цвета фона действуют как ColorDrawable
Ахил Папа
Лучшее и самое простое решение из всего вышеперечисленного.
4gus71n
6

Для тех, кто хочет сделать это без создания фонового сектора, просто добавьте эти строки в TextView

android:background="?android:attr/selectableItemBackground"
android:clickable="true"

Также, чтобы сделать его выбираемым, используйте:

android:textIsSelectable="true"
Дассер Басюни
источник