99 votes

Arrière-plan d'éléments ListView via un sélecteur personnalisé

Est-il possible d'appliquer un arrière-plan personnalisé pour chaque élément de liste via le sélecteur liste?

Le sélecteur par défaut spécifie @android:color/transparent de la state_focused="false" des cas, mais en changeant de cet personnalisé drawable n'affecte pas les éléments qui ne sont pas sélectionnés. Romain Guy semble suggérer dans cette réponse, que cela est possible.

Je suis en train de réaliser le même effet en utilisant un arrière-plan personnalisé sur chaque point de vue et de le cacher lorsque l'élément est sélectionné/concentré/peu importe si le sélecteur est indiqué, mais il serait plus élégant d'avoir ce tous définis dans un seul endroit.

Pour référence, c'est le sélecteur j'utilise pour essayer et obtenir de ce travail:

<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:state_focused="false"
        android:drawable="@drawable/list_item_gradient" />

    <!-- Even though these two point to the same resource, have two states so the drawable will invalidate itself when coming out of pressed state. -->
    <item android:state_focused="true" android:state_enabled="false"
        android:state_pressed="true"
        android:drawable="@drawable/list_selector_background_disabled" />
    <item android:state_focused="true" android:state_enabled="false"
        android:drawable="@drawable/list_selector_background_disabled" />

    <item android:state_focused="true" android:state_pressed="true"
        android:drawable="@drawable/list_selector_background_transition" />
    <item android:state_focused="false" android:state_pressed="true"
        android:drawable="@drawable/list_selector_background_transition" />

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

</selector>

Et ce est la façon dont je suis le réglage du sélecteur:

<ListView
    android:id="@android:id/list"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:listSelector="@drawable/list_selector_background" />    

Merci d'avance pour toute aide!

129voto

dgmltn Points 1939

J'ai été frustré par moi-même et enfin résolu. Comme Romain Guy laissé entendre, il y a un autre état, "android:state_selected", que vous devez utiliser. Utiliser un état drawable pour le fond de votre élément de la liste, et utiliser un autre état drawable pour listSelector de votre liste:

list_row_layout.xml:

<?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="?android:attr/listPreferredItemHeight"
    android:background="@drawable/listitem_background"
    >
...
</LinearLayout>

listitem_background.xml:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_selected="true" android:drawable="@color/android:transparent" />
    <item android:drawable="@drawable/listitem_normal" />
</selector>

layout.xml qui comprend la liste:

...
<ListView 
   android:layout_width="fill_parent"
   android:layout_height="wrap_content"
   android:listSelector="@drawable/listitem_selector"
   />
...

listitem_selector.xml:

<?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/listitem_pressed" />
    <item android:state_focused="true" android:drawable="@drawable/listitem_selected" />
</selector>

79voto

Michał K Points 3304

La solution par dglmtn ne fonctionne pas lorsque vous avez un 9-patch dessinés avec rembourrage en arrière-plan. Des choses étranges se passent, je ne veux même pas en parler, si vous avez ce problème, vous les connaissez.

Maintenant, Si vous voulez avoir une listview avec les différents états et 9-patch un drawable (il serait de travailler avec tout un drawable et les couleurs, je pense) que vous avez à faire 2 choses:

  1. Réglez le sélecteur pour les éléments de la liste.
  2. Se débarrasser du sélecteur par défaut pour la liste.

Ce que vous devez faire est d'abord de définir la row_selector.xml:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
    <item android:state_enabled="true" 
     android:state_pressed="true" android:drawable="@drawable/list_item_bg_pressed" />
    <item android:state_enabled="true"
     android:state_focused="true" android:drawable="@drawable/list_item_bg_focused" />
    <item android:state_enabled="true"
     android:state_selected="true" android:drawable="@drawable/list_item_bg_focused" />
    <item
     android:drawable="@drawable/list_item_bg_normal" />
</selector>

N'oubliez pas l' android:state_selected. Il fonctionne comme android:state_focused pour la liste, mais il est appliqué pour l'élément de la liste.

Maintenant, appliquez le sélecteur d'éléments (row.xml):

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="@drawable/row_selector"
>
...
</RelativeLayout>

Faire un transparent sélecteur pour la liste:

<ListView
    android:id="@+id/android:list"
    ...
    android:listSelector="@android:color/transparent"
    />

Ceci devrait faire l'affaire.

17voto

cV2 Points 2073

Ne jamais utiliser une "couleur d'arrière-plan" pour vos lignes listview ...

cela bloquera chaque action de sélecteur (c'était mon problème!)

bonne chance!

5voto

Scott D. Strader Points 156

L'article "Pourquoi ma liste est-elle noire? Une optimisation Android" du blog Android Developers explique en détail pourquoi l'arrière-plan de la liste devient noir lors du défilement. Réponse simple: définissez cacheColorHint sur votre liste sur transparent (# 00000000).

4voto

Butters Points 146

au lieu de: android: drawable = "@ color / transparent" écrire android: drawable = "@ android: color / transparent"

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X