2010-02-02 14 views
45

Ho una lista semplice con un listino come questo.ListSelector si applica all'intero elenco

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

Come si può vedere Android: listSelector = "# 99 milioni", ma il colore "alpha nero" viene applicato a tutta la lista, non l'elemento selezionato.


Quindi questo è quello che ho adesso, ma l'intero elenco ancora gira nera

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

:: il tag xml nella mia lista

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

Cosa cartella faccio a mettere il file per il selettore a? – Breedly

+2

C'era un bug in tutte le versioni precedenti a HoneyComb che applicava un selettore di lista ** color ** all'intero background dell'elenco. [Leggi la mia risposta ad un'altra domanda] (http://stackoverflow.com/a/15873704/383414) per maggiori dettagli su questo. Questo non è un problema usando le immagini per lo sfondo, quindi tutti i metodi qui sotto. –

risposta

28

Ho avuto lo stesso problema. Ho un'immagine di sfondo personalizzata e non voglio dover creare varianti di quell'immagine di sfondo perché sarebbe noioso rappresentare tutti i diversi stati.

Quindi voglio fare la cosa ovvia, avere una barra semitrasparente che è sovrapposta sopra il listino focalizzato e quando l'utente tocca il tasto "invio" o qualsiasi altra cosa, lampeggia sul colore di sovrapposizione premuto che è più sorprendente e un po 'più opaco.

La soluzione era stare lontano da qualsiasi @color o @drawable che si riferisce a un colore all'interno di listSelector. Ho creato due file .png 3x3 pixel. Ogni salvato con lo strato gamma. Nel mio caso sono due dello stesso colore miscelati in Gimp con una trasparenza diversa sul livello del colore. Quindi quando selezioni un oggetto ottieni una sovrapposizione con il 25% di colore e quando lo premi ottieni una png con il 50% di colore. Li ho messi nel mio drawable come bg_list_item_pressed.png e bg_list_item_highlighted.png

Poi ho impostato il mio selettore di lista per:

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

poi ho aggiunto il mio listSelector attribuisce alla mia ListView nel mio layout xml:

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

Ora funziona esattamente come voglio che funzioni. Compreso l'utilizzo del D-pad per selezionare una riga e fare clic con il tasto Invio.Ottenere l'evidenziazione e la successiva pressione dei colori esattamente come dovrebbero essere.

+5

la domanda rimane: perché non possiamo usare un ColorDrawable per un singolo stato? Creare un'immagine 3px per rappresentare un colore è solo una soluzione, non una soluzione adeguata. – Matthias

+0

Grazie! Mi hai risparmiato un sacco di problemi con questo trucco !! –

+0

Grazie mille !! funziona come un fascino !! – ranjith

2

Il selettore lista è un StateListDrawable — contiene riferimento a più drawable per ogni stato la lista può essere, come selezionato, si è concentrata, pressato, disabili ...

Nel tuo caso, impostando una colore singolo, la lista sta disegnando # 9000 per ogni singolo stato.

È necessario definire un StateListDrawable come descritto sopra, con XML simile al seguente. Questo è ciò che hai impostato nell'attributo 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> 

Oppure, per impostare lo stesso selettore di lista per tutti gli elenchi nella vostra applicazione, è possibile ignorare il selettore nel tema Widget.ListView:

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

Ciao ancora non funziona, vedere sopra – jax

2

Jax,

stavo cercando di capire perché la mia intera lista stava cambiando l'impostazione del listSelector colore, e abbiamo scoperto che questo è esattamente quello che deve fare, cioè stiamo impostando il colore per l'intera lista, e non la riga che è ciò che vogliamo.

Ecco cosa si vuole fare: Presumo che tu abbia un ListView definito in XML. E per questo ListView, presumo tu stia utilizzando un adattatore di qualche tipo per impostare i dati presenti. Anche per questo adattatore, stai usando una vista a righe definita in XML. Che cosa si vuole fare è impostare lo sfondo di questo elemento fila come questo:

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

Ecco il mio textview_selector.xml immagazzinate nella drawable:

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

Spero che questo aiuti

+1

questo è buono, ma ho scoperto che non funziona come mi aspettavo in quanto la vista dell'adattatore non è sicuro su quale vista mettere a fuoco in seguito (presumibilmente solo l'adattatore lo sa). Sicuramente come funziona il ListView di serie deve essere documentato da qualche parte, in quanto è molto più veloce del mio codice, quindi voglio usare quello –

+2

questo è assolutamente sbagliato, AFAIK – manmal

88

stavo avendo questo stesso problema e mentre guardavo uno dei file XML disegnabili della piattaforma ho notato un modo per eliminare la necessità di creare un file immagine solo per un colore, creando una forma in XML.

Ad esempio, invece di:

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

Do:

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

Beyond solo creando un drawable colore normale, la forma è flessibile, simile ad un semplice oggetto vettoriale. Tutti i dettagli possono essere trovati qui: http://developer.android.com/guide/topics/resources/drawable-resource.html#Shape

+3

SÌ! Grazie, l'unica risposta che ho visto che in realtà risolve il problema come dichiarato senza aggirarlo. –

+1

Perché non si tratta di una soluzione alternativa? Evita ancora di utilizzare direttamente le risorse di colore semplice, che è ciò che gli altri workaround aggirano. – JulianSymes

+2

Non so come utilizzare valori di colore esadecimali trasformi una soluzione per un problema diverso in una soluzione alternativa, ma come menzionato nella documentazione collegata, puoi anche utilizzare le risorse colore. '' –

17

Se si imposta un layout di riga per ogni elemento nell'elenco, questo è il modo in cui lo faccio. Notare il valore trasparente impostato su listSelector. (Per brevità, ho rimosso il 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

Questa dovrebbe essere la risposta accettata perché non dipende da alcuni "pixel di soluzione alternativa". –

+0

Lo conosci Sven Jacobs! – worked

+0

Grazie, questo funziona davvero – Kibi

1

Non sempre è necessario creare un'immagine, è possibile definire 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

Penso che questo sia molto meglio della risposta di Eric. In questo modo non ingombrare il tuo progetto con risorse inutili. – MinceMan

Problemi correlati