Seletor na cor de plano de fundo do TextView

121

Estou tentando alterar a cor de segundo plano de um TextViewwidget Android quando o usuário toca nele. Eu criei um seletor para esse fim, que é armazenado res/color/selector.xmle mais ou menos assim:

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

O clickableatributo do TextViewé true, caso isso seja interessante.

Quando atribuo esse seletor a um TextViewas android:background="@color/selector", estou recebendo a seguinte exceção em tempo de execução:

ERROR / AndroidRuntime (13130): Causado por: org.xmlpull.v1.XmlPullParserException: Arquivo XML binário linha # 6: tag requer um atributo 'drawable' ou marca filho que define um drawable

Quando altero o atributo para drawable, ele funciona, mas o resultado parece completamente errado porque os IDs parecem ser interpretados como referências de imagem em vez de referências de cores (como sugere o "drawable").

O que me confunde é que eu posso definir uma referência de cor, por exemplo "@ color / black", como o atributo background diretamente. Isso está funcionando como esperado. O uso de seletores não funciona.

Também posso usar o seletor como textColorsem problemas.

Qual é a maneira correta de aplicar um seletor de cores de fundo a um TextViewno Android?

digitalbreed
fonte
Uma cor pode ser interpretada como um desenho. Como o resultado está errado exatamente?
Romain Guy
Não está mostrando a cor, mas uma imagem dos meus recursos desenháveis ​​como plano de fundo.
digitalbreed
2
O exemplo acima deve funcionar, se você usa android: drawable, não android: color - pelo menos nesse caso funciona para mim: android: drawable = "@ color / my_custom_color". Minhas cores são definidas em values ​​/ colors.xml
#

Respostas:

226

O problema aqui é que você não pode definir a cor do plano de fundo usando um seletor de cores; você precisa de um seletor desenhável . Portanto, as alterações necessárias seriam assim:

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

Você também precisaria mover esse recurso para o drawablediretório em que faria mais sentido, pois não é um seletor de cores em si.

Então você teria que criar o res/drawable/selected_state.xmlarquivo assim:

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

e, finalmente, você usaria assim:

android:background="@drawable/selector"

Nota : a razão pela qual o OP estava obtendo um recurso de imagem desenhado é provavelmente porque ele tentou apenas referenciar seu recurso que ainda estava no diretório de cores, mas usando-o @drawablepara terminar com uma colisão de ID, selecionando o recurso errado.

Espero que isso ainda possa ajudar alguém, mesmo que o OP provavelmente já tenha resolvido o problema.

Benoit Martin
fonte
1
Obrigado, Benoit. O problema foi resolvido (devo admitir, não me lembro exatamente como fiz isso no final) e o projeto foi concluído com êxito. Agradeço que você voltou aqui para postar e ajudar as pessoas a enfrentar o mesmo problema no futuro, grande espírito!
digitalbreed
Eu não posso fazer isso funcionar. Estou tentando aplicá-lo a um botão e ele define o plano de fundo para a cor padrão do seletor, mas não muda para a forma definida em state_pressed. O que eu poderia estar perdendo? Eu posso abrir uma nova pergunta, caso você possa me apontar na direção certa.
Maragues
@ Maragues é difícil dizer sem ver nenhum código. Eu recomendo que você abra uma nova pergunta e publique o código relevante para que possamos descobrir o que pode estar errado. Você pode adicionar um comentário a esta postagem com um link para sua nova postagem.
Benoit Martin
9
Por que simplesmente não usar "drawable =" @ color / your_color "diretamente nos itens do seletor? Você não precisa definir formas ou outros arquivos, apenas definir as definições de cores em values ​​/ colors.xml (sempre é bom não às cores codificar).
javaxian
Não está funcionando. Está me mostrando a cor diferente do que eu declarei em xml de forma.
Er.Rohit Sharma
121

A solução da Benoit funciona, mas você realmente não precisa incorrer na sobrecarga para desenhar uma forma. Como as cores podem ser desenhadas, basta definir uma cor no arquivo /res/values/colors.xml:

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

E use como tal em seu seletor:

<?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
fonte
Por algum motivo, sua solução não está mostrando a cor, mas uma imagem aleatória da minha pasta de recursos desenhados. Tentei limpar o projeto / corrigir propriedades / salvar novamente / reabrir o eclipse, pois parece realmente estranho, mas sem sucesso. Esquisito.
Yahel
@ Yahel Você possivelmente nomeou o recurso de desenho de cores igual a um arquivo de desenho real?
Jonas
@Jona: Não, mas o drawable foi nomeado background_application e o drawable color foi nomeado background_white_transparent. Ambos tinham antecedentes neles ... Eu vi em alguns outros tópicos a mesma coisa acontecer com outros, então arquivei isso como um dos inúmeros bugs do Android e reformulei meu layout inteiro para contornar isso.
Yahel
@Yahel Mmm ... Bem, eu vejo essa questão, mas no meu caso não os mesmos nomes de arquivo ... Caixa minhas perguntas aqui stackoverflow.com/questions/9004744/...
Jona
não conseguiu fazê-lo funcionar, a resposta de Benoit Martin funcionou bem.
Emmanuel Touzery
83

Uma solução ainda mais simples para o acima exposto:

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

Salve isso na pasta drawable e pronto.

Jason Robinson
fonte
1
Talvez isso funcione, mas oficialmente não é suportado (o Android Studio trata isso como um erro).
Blackhex 30/09
@Blackhex Strange. Funciona bem para mim no Eclipse. Provavelmente é um erro de cotão e, se for, você poderá desativá-lo ou ignorá-lo.
Jason Robinson
6
É isso que eu consideraria a solução.
Lay González
<item android:state_pressed="true" android:color="@color/vantablack"/>parece semanticamente idêntico para<item android:state_pressed="true"><color android:color="@color/vantablack"/></item>
samis 14/07/19
16

Até isso funciona.

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

Eu adicionei o android:drawableatributo a cada item e seus valores são cores.

A propósito, por que eles dizem que esse coloré um dos atributos de selector? Eles não escrevem o que android:drawableé necessário.

Recurso da lista de estados de cores

<?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>
Maksim Dmitriev
fonte
atributo de cor funciona quando você está definindo em cores TextView mas não com fundo como realmente as cores no backround são agiu como ColorDrawable
Dad Akhil
Melhor e mais fácil solução para implementar tudo acima.
precisa saber é o seguinte
6

Para quem está procurando fazer isso sem criar um setor em segundo plano, basta adicionar essas linhas ao TextView

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

Também para torná-lo selecionável:

android:textIsSelectable="true"
Dasser Basyouni
fonte