web-dev-qa-db-fra.com

Mettre en surbrillance la ligne sélectionnée ListView

J'ai une liste d'albums (plusieurs centaines) . Lorsque je touche l'album sélectionné, je veux offrir à l'utilisateur le choix de lire l'album en entier ou de passer à sa piste ListView. Pas de problème . Cependant, après avoir touché l'ablum dans albumListView, je veux que la ligne reste en surbrillance afin que l'utilisateur sache sur quel élément il a cliqué et puisse ensuite passer à OK ou à PLAY. Comment mettre en évidence une ligne dans ListView?

37
user611089

Cité de http://Android-developers.blogspot.de/2008/12/touch-mode.html

Imaginez une application simple, ApiDemos par exemple, qui affiche une liste d'éléments de texte. L’utilisateur peut naviguer librement dans la liste à l’aide de la boule de commande mais aussi, alternativement, faire défiler la liste à l’aide de l’écran tactile. La question dans ce scénario est de savoir comment gérer correctement la sélection lorsque l’utilisateur manipule la liste via l’écran tactile.

Dans ce cas, si l'utilisateur sélectionne un élément en haut de la liste puis jette la liste vers le bas, qu'adviendra-t-il de la sélection? Devrait-il rester sur l'élément et faire défiler l'écran? Que devrait-il se passer si l'utilisateur décidait alors de déplacer la sélection avec le trackball? Ou pire, que devrait-il se passer si l'utilisateur appuie sur la boule de commande pour agir sur l'élément actuellement sélectionné, ce qui n'est plus affiché à l'écran?

Après mûre réflexion, nous avons décidé de supprimer complètement la sélection lorsque l'utilisateur manipule l'interface utilisateur via l'écran tactile.

En mode tactile, il n'y a pas de mise au point ni de sélection. Tout élément sélectionné dans une liste de dans une grille est désélectionné dès que l'utilisateur passe en mode tactile. De même, tous les widgets ciblés deviennent flous lorsque l'utilisateur passe en mode tactile. L'image ci-dessous illustre ce qui se produit lorsque l'utilisateur touche une liste après avoir sélectionné un élément avec la boule de commande.

35
Maaalte

Autre solution (principalement en XML)

1) réglez la choiceMode de la ListView sur singleChoice

<ListView
    Android:choiceMode="singleChoice"
.../>

2) Les éléments de la liste doivent être un Checkable Voir et utiliser un Color State List comme arrière-plan

par exemple: album_item.xml

<?xml version="1.0" encoding="utf-8"?>
<CheckedTextView xmlns:Android="http://schemas.Android.com/apk/res/Android"
   Android:background="@drawable/list_selector"
.../>

3) l’état de la couleur d’arrière-plan (list_selector.xml) définit la couleur de surbrillance

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:Android="http://schemas.Android.com/apk/res/Android">
    <item Android:drawable="@color/green" Android:state_checked="true"/>
    <item Android:drawable="@color/green" Android:state_pressed="true"/>
</selector>
42
Hiep

Maaalte est correct, les listes en mode tactile n'affichent pas la surbrillance de la mise au point sur un élément en cours car il n'y a aucun élément en cours en mode tactile. La sélection avec état, comme vous le décrivez, persiste pendant que vous interagissez avec d'autres parties de l'interface utilisateur est un autre problème.

Vous pouvez utiliser CHOICE_MODE_SINGLE pour exprimer une sélection avec état dans une liste. Il traitera la sélection comme un état vérifié. Tant que la vue renvoyée par votre adaptateur implémente l'interface Checkable, vous pouvez afficher l'état sélectionné comme bon vous semble. (Définir un arrière-plan sur la vue des éléments ou autrement. Il n'est pas nécessaire d'afficher un widget de case à cocher.) Vous pouvez ensuite utiliser les méthodes de contrôle des éléments de ListView pour manipuler ou déterminer la sélection.

19
adamp

J'ai résolu ce problème en développant ListView et en surchargeant la méthode getView (). J'ai conservé un identifiant interne pour l'état "sélectionné" et modifié l'arrière-plan de l'élément en fonction de celui-ci, comme suit:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
View currView = super.getView(position, convertView, parent);
StateListItem currItem = getItem(position);
if (currItem.isItemSelected) {
    currView.setBackgroundColor(Color.RED);
} else {
    currView.setBackgroundColor(Color.BLACK);
}
return currView;
}  

J'ai un exemple de programme sur mon billet de blog: http://udinic.wordpress.com/2011/07/01/selectablelistview-make-selection-work/

12
Udinic

Voici ma solution Listview: 

<ListView
        Android:id="@+id/list"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        Android:background="@Android:color/white"
        Android:divider="@Android:color/darker_gray"
        Android:dividerHeight="1dp"
        Android:paddingLeft="10dip"
        Android:paddingRight="10dip"
        Android:choiceMode="singleChoice"
        Android:paddingTop="8dip" >
    </ListView>

Ecrivez un sélecteur pour list_row sous la forme

<!-- <item Android:drawable="@color/Android:transparent"  Android:state_selected="true" /> -->
<item Android:drawable="@Android:color/darker_gray" Android:state_selected="true"/>
<item Android:drawable="@Android:color/darker_gray" Android:state_activated="true"/>    
<item Android:drawable="@Android:color/darker_gray" Android:state_pressed="true"/>
<item Android:drawable="@color/Android:transparent"/>

Assurez-vous que vous avez item pour state_activated = true

Ajoutez ensuite ce sélecteur en tant qu'arrière-plan list_row.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
  Android:layout_width="match_parent"
  Android:layout_height="match_parent"
  Android:background="@drawable/listitem_selector"
  Android:orientation="vertical" >

<TextView
    Android:id="@+id/itemName"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent" />

11
subair_a

ajouter Android:background="?activatedBackgroundIndicator 
pour afficher la disposition principale de l'élément similaire à Android.R.layout.simple_list_item_activated_2.xml

6
denis

Implémentez votre liste avec le mode de choix unique: Android:choiceMode=singleChoice

Tout comme le Android.R.layout.simple_list_item_single_choice par défaut utilise une RadioButton pour indiquer le choix sélectionné, vous pouvez implémenter un état de surbrillance personnalisé ou similaire dans la présentation de votre élément de liste pour répondre aux modifications apportées. Des méthodes telles que getCheckedItemPosition() peuvent être utilisées par votre application pour déterminer l'élément sélectionné par l'utilisateur, si nécessaire.

J'espère que cela pourra aider!

5
Devunwired

Je sais que cette question était active depuis deux ans, mais au cas où quelqu'un en aurait besoin à l'avenir Voici mon code XML ListView

<ListView
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:id="@+id/results"
        Android:choiceMode="singleChoice"
        Android:listSelector="#ffdb700b"/>

Vous voulez changer la valeur Android:listSelector.

4
jrsall92

La solution suivante peut être utilisée pour mettre en évidence un ou plusieurs éléments de la liste. Point de départ: un objet ListFragment permet d'afficher une liste de MyEntity via une implémentation ArrayAdapter. La couleur d'un TextView faisant partie de la disposition de l'élément doit passer au gris si l'élément est sélectionné. Plusieurs articles devraient être sélectionnables.

  1. ListFragment doit fournir un élément OnItemSelectListener (élément YourEntity) qui sera appelé dans onListItemClicked ().

    public void onListItemClick(ListView l, View v, int position, long id) {
      MyEntity entity = (MyEntity) getListView().getItemAtPosition(position);
      if (entityListSelectListener != null) 
        itemSelectListener.onItemSelect(entity); }
    
  2. ArrayAdapter possède une liste pour les champs de clé pour les éléments sélectionnés et fournit les méthodes de gestionnaire addSelection (MyEntity) et clearAllSelections (). La méthode overriden getView () lit la liste des champs de clé et, si la position réelle y figure, modifie la couleur de TextView en gris, sinon en transparent.

    public View getView(int position, View convertView, ViewGroup parent) {
      ...
      if (selectedEntityList.contains(entity.key)) //... highlight view field }
    
  3. Dans onCreate () de l'activité propriétaire, les écouteurs doivent être implémentés pour gérer ArrayAdapter: appeler addSelection () et notifyDataSetChanged ().

    entityListFragment.setEntityListSelectListener(
      new EntityListFragment.OnItemSelectedListener() {
        public void onItemSelect(MyEntity entity) {
        aa.addSelection(entity);
        aa.notifyDataSetChanged(); }});
    
3

J'ai eu le même problème, je l'ai résolu en collant le code suivant dans le code ListView

Android:choiceMode="singleChoice"
Android:listSelector="#003366"

Le fichier XML ressemble à ceci

<?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="fill_parent">

<ListView
    Android:id="@+id/file_list"
    Android:layout_width="fill_parent"
    Android:layout_height="wrap_content"
    Android:choiceMode="singleChoice"
    Android:listSelector="#003366"/>

<Button
    Android:id="@+id/select"
    Android:layout_width="fill_parent"
    Android:layout_height="wrap_content"
    Android:text="SELECT"
    Android:layout_below="@id/file_list"/>

</RelativeLayout>
2
Rijul Gupta

Dans mon cas, lors de l'utilisation de simple_list_item_2, la seule solution consistait à remplacer la méthode getView () de l'adaptateur et à modifier manuellement la couleur de fond:

listview = new SimpleAdapter(ctx, data,
                Android.R.layout.simple_list_item_2, res,
                new String[] {"field1", "field2" },
                new int[] {Android.R.id.text1, Android.R.id.text2 })

            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                View view = super.getView(position, convertView, parent);

                if (this_is_the_selected_item)
                {
                    view.setBackgroundColor(0xff999999);
                }
                else
                {
                    view.setBackgroundColor(Color.BLACK);
                }
                return view;
            }
        };

N'oubliez pas d'appeler listview.invalidateViews () chaque fois que vous modifiez l'élément sélectionné.

1
CpnCrunch

Voici ce que j'ai fait :) - après que la tête principale frappe contre le mur.

Pour l'adaptateur:

 radioAdapter = new RadioAdapter(context, R.layout.row_layout, yourData);

Pour le row_layout.xml:

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:id="@+id/radio_name"
Android:layout_width="fill_parent"
Android:layout_height="fill_parent"
Android:layout_gravity="center_vertical"
Android:padding="10dp"
Android:background="?android:attr/activatedBackgroundIndicator"
Android:clickable="true"
Android:text="SOME RADIO"
Android:textColor="@color/Gray"
Android:textSize="25dp" />

Pour définir une position par défaut à mettre en surbrillance, procédez comme suit pour votre objet listView:

radioTitleList.setItemChecked (defaultPosition, true);

Si vous souhaitez surligner lorsque vous cliquez sur la liste:

Dans votre getView () dans votre adaptateur de liste personnalisé, ajoutez ceci avant de retourner la vue:

 row.setOnClickListener(new OnClickListener() 
 {
 @Override
 public void onClick(View arg0) 
 {
     radioTitleList.setItemChecked(position, true);
             // other stuff like navigating to a new activity etc
     }
 });
0
ryvianstyron