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?


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.


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>

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.


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>

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"
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.