Selettore sul colore di sfondo di TextView


121

Sto tentando di cambiare il colore di sfondo di un TextViewwidget Android quando l'utente lo tocca. Ho creato un selettore per quello scopo, che è memorizzato res/color/selector.xmle più o meno simile a questo:

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

L' clickableattributo di TextViewè true, nel caso sia di interesse.

Quando assegno questo selettore a un TextViewas android:background="@color/selector", ottengo la seguente eccezione in fase di esecuzione:

ERRORE / AndroidRuntime (13130): causato da: org.xmlpull.v1.XmlPullParserException: riga di file XML binario n. 6: il tag richiede un attributo 'drawable' o un tag figlio che definisce un drawable

Quando cambio l'attributo in drawable, funziona, ma il risultato sembra completamente sbagliato perché gli ID sembrano essere interpretati come riferimenti di immagine invece che come riferimenti di colore (come suggerisce il "drawable").

Ciò che mi confonde è che posso impostare un riferimento di colore, ad esempio "@ color / black", come attributo di sfondo direttamente. Funziona come previsto. L'uso dei selettori non funziona.

Posso anche usare il selettore come il textColorsenza problemi.

Qual è il modo corretto per applicare un selettore del colore di sfondo a un TextViewin Android?


Un colore può essere interpretato come un disegnabile. In che modo il risultato è sbagliato esattamente?
Romain Guy,

Non mostra il colore ma un'immagine dalle mie risorse disegnabili come sfondo.
digitalbreed

2
Quanto sopra dovrebbe funzionare, se usi android: drawable, non android: color - almeno in questo caso funziona per me: android: drawable = "@ color / my_custom_color". I miei colori sono definiti in values ​​/ colors.xml
AgentKnopf

Risposte:


226

Il problema qui è che non è possibile definire il colore di sfondo utilizzando un selettore di colori, è necessario un selettore disegnabile . Quindi, le modifiche necessarie sarebbero simili a questa:

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

Dovresti anche spostare quella risorsa nella drawabledirectory in cui avrebbe più senso poiché non è un selettore di colori di per sé.

Quindi dovresti creare il res/drawable/selected_state.xmlfile in questo modo:

<?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 infine, lo useresti in questo modo:

android:background="@drawable/selector"

Nota : il motivo per cui l'OP stava ottenendo una risorsa immagine disegnata è probabilmente perché ha cercato di fare riferimento solo alla sua risorsa che era ancora nella directory dei colori ma utilizzando @drawablecosì si è concluso con una collisione ID, selezionando la risorsa sbagliata.

Spero che questo possa ancora aiutare qualcuno anche se l'OP probabilmente ha, spero, risolto il suo problema ormai.


1
Grazie, Benoit. Il problema è stato risolto (devo ammetterlo, non ricordo esattamente come ho fatto alla fine) e il progetto è stato portato a termine con successo. Apprezzo che tu sia tornato qui per pubblicare e aiutare le persone a dover affrontare lo stesso problema in futuro, grande spirito!
digitalbreed

Non posso farlo funzionare. Sto provando ad applicarlo a un pulsante e imposta lo sfondo sul colore predefinito del selettore, ma non cambia nella forma definita in state_pressed. Cosa potrei perdermi? Potrei aprire una nuova domanda, nel caso tu possa indicarmi la giusta direzione.
Maragues

@ Maragues è difficile da dire senza vedere alcun codice. Ti consiglio di aprire una nuova domanda e pubblicare il codice pertinente in modo che possiamo capire cosa potrebbe essere sbagliato. Puoi anche aggiungere un commento a questo post con un link al tuo nuovo post.
Benoit Martin

9
Perché non utilizzare semplicemente "drawable =" @ color / your_color "direttamente negli elementi del selettore? Non è necessario definire forme o altri file di sorta, basta avere le definizioni dei colori in values ​​/ colors.xml (va sempre bene non codificare i colori).
javaxian

Non funziona. Mi mostra il colore diverso da entrambi che ho dichiarato in forma xml.
Er.Rohit Sharma

122

La soluzione di Benoit funziona, ma non è davvero necessario sostenere l'overhead per disegnare una forma. Poiché i colori possono essere disegnabili, è sufficiente definire un colore in un file /res/values/colors.xml:

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

E poi usa come tale nel tuo selettore:

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

Per qualche ragione, la tua soluzione non sta mostrando il colore ma un'immagine casuale dalla mia cartella delle risorse disegnabili. Ho provato a pulire il progetto / correggere le proprietà / resave / riaprire eclipse perché sembra davvero strano, ma senza alcun risultato. Strano.
Yahel

@Yahel Hai forse chiamato la risorsa del colore disegnabile come un vero file disegnabile?
Jona

@ Jona: No, ma il drawable si chiamava background_application e il drawable di colore si chiamava background_white_transparent. Entrambi avevano uno sfondo in loro ... Ho visto su qualche altro thread la stessa cosa accadere ad altri, quindi l'ho segnalato come uno dei numerosi bug di Android e ho rinnovato il mio intero layout per risolverlo.
Yahel

@Yahel Mmm ... Beh, vedo quel problema ma nel mio caso non gli stessi nomi di file ... Controlla le mie domande qui stackoverflow.com/questions/9004744/…
Jona

non è riuscito a farlo funzionare, la risposta di Benoit Martin ha funzionato bene.
Emmanuel Touzery

83

Una soluzione ancora più semplice a quanto sopra:

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

Salvalo nella cartella disegnabile e sei a posto.


1
Forse funziona, ma ufficialmente non è supportato (Android Studio lo considera un errore).
Blackhex

@Blackhex Strange. Funziona bene per me in Eclipse. Probabilmente è un errore di Lint e, in tal caso, dovresti essere in grado di disabilitarlo o ignorarlo.
Jason Robinson,

6
Questo è ciò che considererei la soluzione.
Lay González

<item android:state_pressed="true" android:color="@color/vantablack"/>sembra semanticamente identico a<item android:state_pressed="true"><color android:color="@color/vantablack"/></item>
samis

16

Anche questo funziona.

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

Ho aggiunto l' android:drawableattributo a ogni articolo e i loro valori sono i colori.

A proposito, perché dicono che colorè uno degli attributi di selector? Non scrivono che android:drawableè richiesto.

Risorsa elenco stato colore

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

l'attributo color funziona quando si impostano i colori della visualizzazione del testo ma non con lo sfondo poiché in realtà i colori sullo sfondo vengono utilizzati come ColorDrawable
Akhil Dad

La soluzione migliore e più semplice da implementare di tutti sopra.
4gus71n

6

Per chi sta cercando di farlo senza creare un settore di sfondo, è sufficiente aggiungere quelle linee al file TextView

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

Inoltre per renderlo selezionabile utilizzare:

android:textIsSelectable="true"
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.