2010-02-02 23 views
45

Tengo una lista simple con un selector de listas como tal.ListSelector se aplica a toda la lista

<ListView android:id="@+id/list" android:layout_width="fill_parent" 
    android:layout_height="fill_parent" android:layout_below="@+id/round" 
    android:listSelector="#99000000" android:clickable="true" android:cacheColorHint="#00000000" android:background="#00000000"> 
</ListView> 

Como se puede ver androide: listSelector = "# 99000000" pero el color "negro alfa" se aplica a toda la lista, no es el elemento seleccionado.


Así que esto es lo que tengo ahora, pero toda la lista aún se convierte en negro

:: listview_background.xml

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

:: colors.xml

<resources> 
    <drawable name="list_normal">#96FFFFFF</drawable> 
    <drawable name="list_active">#66000000</drawable> 
    <drawable name="list_pressed">#CA000000</drawable> 
</resources> 

:: la etiqueta xml en mi lista

android:listSelector="@drawable/listview_background" 
+0

qué carpeta debo poner el archivo para el selector en? – Breedly

+2

Hubo un error en todas las versiones anteriores a HoneyComb que aplicaba un selector de lista ** color ** a todo el fondo de la lista. [Vea mi respuesta a otra pregunta] (http://stackoverflow.com/a/15873704/383414) para más detalles sobre esto. Esto no es un problema al usar imágenes para el fondo, por lo tanto, todas las soluciones a continuación. –

Respuesta

28

que tenían el mismo problema. Tengo una imagen de fondo personalizada, y no quiero tener que hacer variantes de esa imagen de fondo porque sería tedioso representar todos los diferentes estados.

Así que quiero hacer lo obvio, tener una barra semitransparente que se superpone sobre el elemento de lista enfocado y cuando el usuario toca la tecla "enter" o lo que sea, parpadea al color de superposición presionado que es más llamativo y algo más opaco.

La solución fue mantenerse alejado de cualquier @color o @drawable que haga referencia a un color dentro de listSelector. Creé dos archivos .png de 3x3 píxeles. Cada uno guardado con la capa gamma. En mi caso, son dos del mismo color, cada uno mezclado en Gimp con una transparencia diferente en la capa de color. Entonces, cuando seleccionas un objeto, obtienes una superposición con un 25% de color, y cuando lo presionas obtienes un png con un 50% de color. Los pongo en mis dibujables como bg_list_item_pressed.png y bg_list_item_highlighted.png

Entonces volví mi selector de la lista a:

<?xml version="1.0" encoding="utf-8"?> 
<selector xmlns:android="http://schemas.android.com/apk/res/android"> 

    <!-- Selected --> 
    <item 
    android:state_focused="true" 
    android:state_pressed="false" 
    android:drawable="@drawable/bg_list_item_highlighted" /> <!-- @drawable/tab_focus --> 

    <!-- Pressed --> 
    <item 
    android:state_pressed="true" 
    android:drawable="@drawable/bg_list_item_pressed" /> <!-- @drawable/tab_press --> 

</selector> 

Luego he añadido mi listSelector atribuye a mi ListView en mi diseño xml:

android:listSelector="@drawable/list_selector" 
android:drawSelectorOnTop="true" 

Ahora funciona exactamente como quiero que funcione. Incluyendo usar el D-pad para seleccionar una fila, y hacer clic en ella con enter.Obteniendo el resaltado y presionando los colores exactamente como deberían ser.

+5

, la pregunta sigue siendo: ¿por qué no podemos usar un ColorDrawable para un solo estado? Crear una imagen de 3px para representar un color es solo una solución temporal, no una solución adecuada. – Matthias

+0

Gracias! ¡Me ahorraste muchos problemas con este truco! –

+0

¡Muchas gracias! ¡funciona como un encanto! – ranjith

2

El selector de la lista es un StateListDrawable — contiene referencia a múltiples dibujables para cada estado de la lista puede ser, como seleccionado, centrado, presionado, discapacitados ...

En su caso, mediante el establecimiento de una color único, la lista está dibujando # 9000 para cada estado.

Debe definir un StateListDrawable como se describió anteriormente, con XML similar al siguiente. Esto es lo que configura en su atributo android:listSelector.

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

O, para establecer la misma lista de selección para todas las listas en la aplicación, puede anular el selector en el tema Widget.ListView:

<style name="Widget.ListView" parent="Widget.AbsListView"> 
    <item name="android:listSelector">@drawable/my_custom_selector</item> 
</style> 
+0

Hola, todavía no funciona, ver más arriba – jax

2

Jax,

yo estaba tratando de averiguar por qué mi lista entera estaba cambiando la configuración del listSelector color, y descubrí que esto es exactamente lo que se supone que debe hacer, es decir, estamos estableciendo el color para la totalidad lista, y no la fila que es lo que queremos.

Esto es lo que quiere hacer: Supongo que tiene un ListView definido en XML. Y para este ListView, supongo que está utilizando un adaptador de algún tipo para establecer presentar los datos. También para este adaptador, está utilizando alguna vista de fila que se define en XML. Lo que se quiere hacer es configurar el fondo de esta fila de elementos de la siguiente manera:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:orientation="horizontal" 
    android:background="@drawable/textview_selector"> 
     <TextView  android:id="@+id/textForList" 
     android:layout_height="fill_parent" 
     android:layout_width="wrap_content" 
     android:padding="10sp" /> 
</LinearLayout> 

Aquí se almacena en mi textview_selector.xml dibujable:

<?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/teal" /> 
    <item android:drawable="@drawable/white" /> 
</selector> 

espero que esto ayude

+1

esto es bueno, pero descubrí que no funciona como esperaba, ya que la vista del adaptador no está segura en qué vista enfocarme a continuación (presumiblemente solo el adaptador lo sabe). Sin duda, la acción de ListView debe estar documentada en alguna parte, ya que es mucho más rápido que mi código, así que quiero usar ese –

+2

, esto es completamente incorrecto, AFAIK – manmal

88

que estaba teniendo este mismo problema y mientras miraba uno de los archivos XML dibujables de la plataforma noté una forma de eliminar la necesidad de crear un archivo de imagen solo para un color, creando una forma en XML.

Por ejemplo, en lugar de:

<item android:state_focused="true" 
     android:drawable="@drawable/list_active" /> 

Do:

<item android:state_focused="true"> 
    <shape> 
     <solid android:color="#66000000" /> 
    </shape> 
</item> 

Más allá de la creación de un dibujable color plano, la forma es flexible, similar a un objeto vectorial simple. Todos los detalles se pueden encontrar aquí: http://developer.android.com/guide/topics/resources/drawable-resource.html#Shape

+3

¡SÍ! Gracias, la única respuesta que he visto que en realidad resuelve el problema tal como se establece sin tener que solucionarlo. –

+1

¿Por qué esto no es una solución? Todavía evita el uso directo de recursos de color normal, que es lo que funcionan con las otras soluciones. – JulianSymes

+2

No sé cómo usar valores de color hexadecimales convierte una solución para un problema diferente en una solución alternativa, pero como se menciona en la documentación vinculada, también puede usar recursos de color. '' –

17

Si está configurando un diseño de fila para cada elemento de la lista, así es como lo hago. Tenga en cuenta el valor transparente establecido en listSelector. (Por razones de brevedad, quité la colors.xml.)

main.xml

<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"> 
    <ListView 
    android:id="@android:id/list" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:listSelector="#00000000"/> 
</LinearLayout> 

row.xml

<FrameLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/row" 
    android:layout_width="fill_parent" 
    android:layout_height="?android:attr/listPreferredItemHeight" 
    android:background="@drawable/list_selector"> 
    ... 
</FrameLayout> 

list_selector.xml

<selector xmlns:android="http://schemas.android.com/apk/res/android"> 
    <item android:state_pressed="true" android:drawable="#66FFFFFF" /> 
    <item android:drawable="#FF666666"/> 
</selector> 
+2

Esta debería ser la respuesta aceptada porque no depende de algunos "píxeles de solución". –

+0

Lo sabes Sven Jacobs! – worked

+0

Gracias, esto realmente funciona – Kibi

1

No siempre se necesita para crear una imagen, puede definir una forma

<?xml version="1.0" encoding="utf-8"?> 

<item android:state_focused="true" android:state_pressed="false"> 
    <shape android:shape="rectangle"> 
     <solid android:color="#40000000"/> 
    </shape> 
</item> 
<item android:state_pressed="true"> 
    <shape android:shape="rectangle"> 
     <solid android:color="#80000000"/> 
    </shape> 
</item> 

+0

Creo que esto es mucho mejor que la respuesta de Eric. De esta forma, no confunde su proyecto con recursos inútiles. – MinceMan

Cuestiones relacionadas