Selector de color de fondo de TextView

121

Estoy intentando cambiar el color de fondo de un TextViewwidget de Android cuando el usuario lo toca. He creado un selector para ese propósito, que se almacena res/color/selector.xmly se ve más o menos así:

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

El clickableatributo de TextViewestrue , en caso de que sea de interés.

Cuando asigno este selector a un TextViewas android:background="@color/selector", obtengo la siguiente excepción en tiempo de ejecución:

ERROR / AndroidRuntime (13130): Causado por: org.xmlpull.v1.XmlPullParserException: archivo XML binario línea # 6: la etiqueta requiere un atributo 'dibujable' o etiqueta secundaria que defina un dibujable

Cuando cambio el atributo a dibujable, funciona, pero el resultado parece completamente incorrecto porque los ID parecen interpretarse como referencias de imagen en lugar de referencias de color (como sugiere el "dibujable").

Lo que me confunde es que puedo establecer una referencia de color, por ejemplo, "@ color / negro", como el atributo de fondo directamente. Esto está funcionando como se esperaba. Usar selectores no funciona.

También puedo usar el selector textColorsin problemas.

¿Cuál es la forma correcta de aplicar un selector de color de fondo a un TextViewen Android?

raza digital
fuente
Un color puede interpretarse como dibujable. ¿Cómo es exactamente el resultado incorrecto?
Romain Guy
No muestra el color, sino una imagen de mis recursos dibujables como fondo.
digitalbreed
2
Lo anterior debería funcionar, si usa android: drawable, no android: color, al menos en ese caso me funciona: android: drawable = "@ color / my_custom_color". Mis colores se definen en values ​​/ colors.xml
AgentKnopf

Respuestas:

226

El problema aquí es que no puede definir el color de fondo con un selector de color, necesita un selector que se pueda dibujar . Entonces, los cambios necesarios se verían así:

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

También necesitaría mover ese recurso al drawabledirectorio donde tendría más sentido ya que no es un selector de color per se.

Entonces tendrías que crear el res/drawable/selected_state.xmlarchivo así:

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

y finalmente, lo usarías así:

android:background="@drawable/selector"

Nota : la razón por la cual el OP estaba obteniendo un recurso de imagen dibujado probablemente es porque trató de hacer referencia a su recurso que todavía estaba en el directorio de colores pero lo usó @drawabley terminó con una colisión de ID, seleccionando el recurso incorrecto.

Espero que esto pueda ayudar a alguien, incluso si el OP probablemente haya resuelto su problema, espero.

Benoit Martin
fuente
1
Gracias Benoit. El problema se resolvió (debo admitir que no recuerdo cómo lo hice exactamente al final) y el proyecto se terminó con éxito. Le agradezco que haya regresado aquí para publicar y ayudar a las personas que enfrentan el mismo problema en el futuro, ¡gran espíritu!
digitalbreed
No puedo hacer que esto funcione. Estoy tratando de aplicarlo a un botón y establece el fondo al color predeterminado del selector, pero no cambia a la forma definida en state_pressed. ¿Qué me podría estar perdiendo? Podría abrir una nueva pregunta, en caso de que pueda señalarme en la dirección correcta.
Maragues
@Maragues es difícil de decir sin ver ningún código. Le recomiendo que abra una nueva pregunta y publique el código relevante para que podamos descubrir qué podría estar mal. También puede agregar un comentario a esta publicación con un enlace a su nueva publicación.
Benoit Martin
9
¿Por qué no usar simplemente "drawable =" @ color / your_color "directamente en los elementos de su selector? No necesita definir ninguna forma ni ningún otro archivo, solo tenga sus definiciones de color en values ​​/ colors.xml (siempre es bueno no codificar colores).
javaxian
No funciona. Me muestra el color diferente de los dos que he declarado en forma de xml.
Er.Rohit Sharma
121

La solución de Benoit funciona, pero realmente no es necesario incurrir en gastos generales para dibujar una forma. Como los colores pueden ser dibujables, solo defina un color en un archivo /res/values/colors.xml:

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

Y luego utilícelo como tal en su selector:

<?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
fuente
Por alguna razón, su solución no muestra el color, sino una imagen aleatoria de mi carpeta de recursos dibujables. Traté de limpiar el proyecto / corregir propiedades / resave / reabrir eclipse ya que parece realmente extraño, pero fue en vano. Extraño.
Yahel
@Yahel ¿Posiblemente nombró el recurso dibujable de color igual que un archivo dibujable real?
Jona
@Jona: No, pero el dibujable se llamó background_application y el color dibujable se llamó background_white_transparent. Ambos tenían antecedentes en ellos ... He visto en algún otro hilo que a otros les pasa lo mismo, así que lo archivé como uno de los numerosos errores de Android y actualicé todo mi diseño para solucionarlo.
Yahel
@Yahel Mmm ... Bueno, veo ese problema, pero en mi caso no son los mismos nombres de archivo ... Mira mis preguntas aquí stackoverflow.com/questions/9004744/…
Jona
no logró hacerlo funcionar, la respuesta de Benoit Martin funcionó bien.
Emmanuel Touzery
83

Una solución aún más simple a lo anterior:

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

Guarde eso en la carpeta dibujable y listo.

Jason Robinson
fuente
1
Tal vez esto funcione, pero oficialmente no es compatible (Android Studio lo trata como un error).
Blackhex
@Blackhex Strange. Funciona bien para mí en Eclipse. Probablemente sea un error de pelusa, y si lo es, debería poder desactivarlo o ignorarlo.
Jason Robinson
66
Esto es lo que consideraría la solución.
Lay González
<item android:state_pressed="true" android:color="@color/vantablack"/>parece semánticamente idéntico a<item android:state_pressed="true"><color android:color="@color/vantablack"/></item>
samis
16

Incluso esto 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>

Agregué el android:drawable atributo a cada elemento, y sus valores son colores.

Por cierto, ¿por qué dicen que colores uno de los atributos de selector? Ellos no escriben esoandroid:drawable se requiere.

Recurso de lista de estado de color

<?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
fuente
El atributo de color funciona cuando se configuran los colores de la vista de texto pero no con el fondo, ya que en realidad los colores del fondo se actúan como ColorDrawable
Akhil Dad
La mejor y más fácil solución para implementar de todo lo anterior.
4gus71n
6

Para quién está buscando hacerlo sin crear un sector de fondo, simplemente agregue esas líneas al TextView

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

También para hacer uso seleccionable:

android:textIsSelectable="true"
Dasser Basyouni
fuente