web-dev-qa-db-fra.com

Changer la couleur d'arrière-plan de l'élément sélectionné sur un ListView

Je souhaite savoir comment modifier la couleur d'arrière-plan de l'élément sélectionné dans ma liste. Je souhaite uniquement modifier l'élément spécifique cliqué par l'utilisateur, ce qui signifie que si l'utilisateur clique sur un autre élément, celui-ci est mis en surbrillance. Eh bien, puisque je veux que ce soit aussi simple que possible et que j'utilise le listview Android par défaut, j'ai utilisé ce code à la place:

record_list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                try{
                    for (int ctr=0;ctr<=record_items.length;ctr++){
                        if(i==ctr){
                            record_list.getChildAt(ctr).setBackgroundColor(Color.CYAN);
                        }else{
                            record_list.getChildAt(ctr).setBackgroundColor(Color.WHITE);
                        }
                    }
                }
                catch (Exception e){
                    e.printStackTrace();
                }
                Log.v("Selected item",record_list.getItemAtPosition(i));
            }
        });

Ok, celui-ci fonctionne mais le problème est qu’il est lent. Maintenant, je veux savoir s’il existe un autre moyen de le faire qui donnera le même résultat que ce que j’ai fait.

J'ai essayé d'utiliser record_list.getSelectedView().setBackgroundColor(Color.CYAN); mais cela me donne une exception de pointeur nulle.

J'ai aussi essayé le fichier selector.xml mais il n'a pas non plus fait l'affaire ..__ De plus, il existe une propriété ici sur ListView qui s'appelle listSelector. C'est un dessin comme le dit la documentation "Dessrable utilisé pour indiquer l'élément actuellement sélectionné dans la liste". Je pense aussi que cela devrait faire l'affaire et que oui, cela fonctionne aussi bien sur mon émulateur que sur mon onglet Galaxy. J'ai aussi essayé les autres méthodes mais rien ne fonctionne comme je le voulais.

49
KaHeL

Vous pouvez suivre la position de l'élément sélectionné en cours:

    OnItemClickListener listViewOnItemClick = new OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> adapter, View arg1, int position, long id) {
                mSelectedItem = position;
                mAdapter.notifyDataSetChanged();
        }
    };

Et substituez la méthode getView de votre adaptateur:

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        final View view = View.inflate(context, R.layout.item_list, null);

        if (position == mSelectedItem) {
            // set your color
        }

        return view;
    }

Pour moi, ça a fait l'affaire.

68
Esteam

Vous pouvez utiliser un sélecteur. Modifiez les valeurs de couleurs et modifiez les paramètres ci-dessous en fonction de vos besoins.

bkg.xml dans un dossier pouvant être dessiné

<?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/pressed" />
<item  Android:state_focused="false" 
    Android:drawable="@drawable/normal" />
</selector>

pressions.xml dans un dossier pouvant être dessiné

<?xml version="1.0" encoding="UTF-8"?> 
<shape xmlns:Android="http://schemas.Android.com/apk/res/Android"> 
<solid Android:color="#FF1A47"/>  // color   
<stroke Android:width="3dp"
        Android:color="#0FECFF"/> // border
<padding Android:left="5dp"
         Android:top="5dp"
         Android:right="5dp"
         Android:bottom="5dp"/> 
<corners Android:bottomRightRadius="7dp" // for rounded corners
         Android:bottomLeftRadius="7dp" 
         Android:topLeftRadius="7dp"
         Android:topRightRadius="7dp"/> 
</shape>

normal.xml dans un dossier pouvant être dessiné

<?xml version="1.0" encoding="UTF-8"?> 
<shape xmlns:Android="http://schemas.Android.com/apk/res/Android"> 
<solid Android:color="#FFFFFF"/>    
<stroke Android:width="3dp"
        Android:color="#0FECFF" />

<padding Android:left="5dp"
         Android:top="5dp"
         Android:right="5dp"
         Android:bottom="5dp"/> 
<corners Android:bottomRightRadius="7dp"
         Android:bottomLeftRadius="7dp" 
         Android:topLeftRadius="7dp"
         Android:topRightRadius="7dp"/> 
</shape>

Définir l’arrière-plan dessinable sur la disposition personnalisée Listview à gonfler pour chaque ligne

Je recommande d'utiliser une liste personnalisée avec un adaptateur personnalisé.

  Android:background="@drawable/bkg"     

Si vous n'avez pas utilisé d'adaptateur personnalisé, vous pouvez définir le sélecteur de liste sur listview comme ci-dessous.

   Android:listSelector="@drawable/bkg" 
67
Raghunandan

Définir variable

private ListView mListView;

Initialise la variable  

mListView = (ListView)findViewById(R.id.list_view);

OnItemClickListener de listview

   mListView.setOnItemClickListener(new OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> adpterView, View view, int position,
                long id) {
            for (int i = 0; i < mListView.getChildCount(); i++) {
                if(position == i ){
                    mListView.getChildAt(i).setBackgroundColor(Color.BLUE);     
                }else{
                    mListView.getChildAt(i).setBackgroundColor(Color.TRANSPARENT);
                }
            }
        }
    });

Construire et exécuter le projet - Terminé

22
Hiren Patel

Si vous souhaitez que l'élément reste en surbrillance après l'avoir cliqué, vous devez le définir manuellement comme étant sélectionné dans l'écouteur onItemClick.

Android ListView élément sélectionné reste en surbrillance :

myList.setOnItemClickListener(new OnItemClickListener() {
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {   
        view.setSelected(true); // <== Will cause the highlight to remain
        //... do more stuff                          
    }});

Cela suppose que vous avez un élément sélectionné par l’état dans votre sélecteur:

<?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="@color/red" />
  <item Android:state_enabled="true" Android:state_focused="true" Android:drawable="@color/red" />
  <item Android:state_enabled="true" Android:state_selected="true" Android:drawable="@color/red" />
  <item Android:drawable="@color/white" />
</selector>
15
ssawchenko

Méthode 1:

Mettez à jour ListView dans votre activité/fragment de mise en page XML:

<ListView
   ...
   Android:choiceMode="singleChoice"
   Android:listSelector="@Android:color/darker_gray"
/>

Ça y est, vous avez terminé! 

Si vous voulez un moyen de gérer cela par programme, utilisez la méthode 2 ...

Méthode 2:  

Si vous utilisez un ListFragment, vous pouvez remplacer onListItemClick () en utilisant la vue pour définir la couleur. Enregistrez la vue sélectionnée pour réinitialiser la couleur de la dernière sélection. 

Veuillez noter que cela ne fonctionne que sur les vues de liste qui tiennent sur un seul écran, car la vue est recyclée.

public class MyListFragment extends ListFragment {
    View previousSelectedItem;
...
    @Override
    public void onListItemClick(ListView parent, View v, int position, long id) {
        super.onListItemClick(parent, v, position, id);
        if (previousSelectedItem!=null) {
            previousSelectedItem.setBackgroundColor(Color.WHITE);
        }
        previousSelectedItem=v;
        v.setBackgroundColor(Color.BLUE);
    }
}
7
JMax

Tout d’abord, vous pouvez créer un fichier xml sélecteur comme ci-dessous dans votre dossier pouvant être dessiné drawable/list_item_selector.xml

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

    <item Android:state_activated="true">
      <shape Android:shape="rectangle">
        <solid Android:color="#333333" />
        <padding Android:left="5dp" Android:right="5dp" />
      </shape></item>
    <item><shape Android:shape="rectangle">
            <solid Android:color="#222222" />
        </shape></item>

</selector>

Et puis dans votre liste de vues spécifiez fond comme

Android:background="@drawable/list_item_selector"
6
Nirali

Pour ceux qui se demandent ce qu’il faut EXACTEMENT faire pour garder les lignes sélectionnées même lorsque vous faites défiler vers le haut. C'est le state_activated Le reste est pris en charge par les fonctionnalités internes, vous n'avez pas à vous soucier de la bascule et vous pouvez sélectionner plusieurs éléments. Je n'avais pas besoin d'utiliser les méthodes notifyDataSetChanged () ou setSelected (true).

Ajoutez cette ligne à votre fichier de sélection, drawable\row_background.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="@Android:color/holo_blue_light"/>

    <item Android:state_enabled="true" Android:state_pressed="true" Android:drawable="@Android:color/holo_blue_light" />
    <item Android:state_enabled="true" Android:state_focused="true" Android:drawable="@Android:color/holo_blue_bright" />
    <item Android:state_enabled="true" Android:state_selected="true" Android:drawable="@Android:color/holo_blue_light" />
    <item Android:state_activated="true" Android:drawable="@Android:color/holo_blue_light" />

    <item Android:drawable="@Android:color/transparent"/>
</selector>

Puis dans layout\custom_row.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="wrap_content"
        Android:padding="10dip"
        Android:background="@drawable/row_background"
        Android:orientation="vertical">
  <TextView
        Android:id="@+id/line1"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content" />
</LinearLayout>

Pour plus d'informations, j'utilise cela avec ListView Adapter, en utilisant myList.setChoiceMode (ListView.CHOICE_MODE_MULTIPLE_MODAL); et myList.setMultiChoiceModeListener (nouveau MultiChoiceModeListener () ...

à partir de cet exemple: http://www.androidbegin.com/tutorial/Android-delete-multiple-selected-items-listview-tutorial/

De plus, vous devriez (devriez) utiliser cette structure pour votre couplage d'adaptateur de liste: List myList = new ArrayList ();

au lieu de: ArrayList myList = new ArrayList ();

Explication: Liste de types vs type ArrayList en Java

5
Emil

utilisez le xml ci-dessous comme fond d’écran pour résoudre tous les problèmes .

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:Android="http://schemas.Android.com/apk/res/Android">
<item Android:drawable="@Android:color/holo_orange_dark" Android:state_pressed="true"/>
<item Android:drawable="@Android:color/holo_green_light" Android:state_selected="true"/>
<item Android:drawable="@Android:color/holo_green_light" Android:state_activated="true"/>

Merci, Nagendra

2
Anisetti Nagendra

Je sais que c'est une vieille question, mais je donne une solution simple à ce besoin (sans boucles!):

//On your adapter create a variable:
private View lastSelectedItem;

//Define the folowing method:
private void toggleBackgroundItem(View view) {
    if (lastSelectedItem != null) {
        lastSelectedItem.setBackgroundColor(Color.TRANSPARENT);
    }
    view.setBackgroundColor(getResources().getColor(R.color.colorPrimaryDark));
    lastSelectedItem = view;

}
//finally invoque the method onItemClick
lvSac.setOnItemClickListener(new AdapterView.OnItemClickListener()

{
    @Override
    public void onItemClick (AdapterView < ? > adapterView, View view,int i, long l){

    toggleBackgroundItem(view);
}
}
2
Eumagnun

Manière la plus simple que j'ai trouvée:

dans votre activité XML, ajoutez ces lignes:

<ListView 
... 
Android:choiceMode="singleChoice"
Android:listSelector="#666666"
/>

ou définissez par programme ces propriétés:

listView.setSelector(Drawable selector)
listView.setSelector(int resourceId)

Mon exemple particulier:

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

grâce à AJG: https://stackoverflow.com/a/25131125/1687010

2
Taochok

Je fais également la même chose: mettez en surbrillance l'arrière-plan de l'élément de la liste sélectionné (changez-le en rouge) et définissez la couleur du texte de l'élément en blanc. 

Je peux penser de manière " simple mais non efficace ": Conserver la position d'un élément sélectionné dans l'adaptateur personnalisé et la modifier dans la variable OnItemClickListener de ListView:

// The OnItemClickListener implementation
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
    mListViewAdapter.setSelectedItem(position);
}

// The custom Adapter
private int mSelectedPosition = -1;
public void setSelectedItem (int itemPosition) {
    mSelectedPosition = itemPosition;
    notifyDataSetChanged();
}

Puis mettez à jour l’arrière-plan et la couleur du texte de l’élément sélectionné dans la méthode getView().

// The custom Adapter
@Override
public View getView(int position, View convertView, ViewGroup parent) {
    ...
    if (position == mSelectedPosition) {
        // customize the selected item's background and sub views
        convertView.setBackgroundColor(YOUR_HIGHLIGHT_COLOR);
        textView.setTextColor(TEXT_COLOR);
    } else {
        ...
    }
}

Après avoir cherché pendant un certain temps, j'ai constaté que beaucoup de personnes avaient parlé de définir Android:listSelector="YOUR_SELECTOR". Après avoir essayé pendant un certain temps, j'ai trouvé le moyen le plus simple de mettre en évidence l'arrière-plan de l'élément ListView sélectionné peut être effectué avec seulement deux lignes définies sur la ressource de présentation de ListView:

Android:choiceMode="singleChoice"
Android:listSelector="YOUR_COLOR"

Il existe également un autre moyen de le faire fonctionner, comme personnaliser le thème activatedBackgroundIndicator. Mais je pense que ce serait une solution beaucoup plus générique car cela affecterait tout le thème.

2
Ethan Zhong

C'est une méthode simple qui peut gérer la sélection même si la liste est longue:

public View getView(final int position, View convertView, ViewGroup parent) {
    // TODO Auto-generated method stub
    Holder holder=new Holder();
    View rowView;
    rowView = inflater.inflate(R.layout.list_item, null);
    //Handle your items.
    //StringHolder.mSelectedItem is a public static variable.
    if(getItemId(position)==StringHolder.mSelectedItem){
        rowView.setBackgroundColor(Color.LTGRAY);

    }else{
        rowView.setBackgroundColor(Color.TRANSPARENT);
    }
    return rowView;
}

Et ensuite dans votre onclicklistener:

list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
            StringHolder.mSelectedItem = catagoryAdapter.getItemId(i-1);
            catagoryAdapter.notifyDataSetChanged();
.....
1
Wasiun A. Khan

supposons que vous souhaitiez cliquer sur un élément à chaque fois. Alors ce code fonctionne bien. Prenons le nom de la liste comme stlist

stList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        // here i overide the onitemclick method in onitemclick listener
            public void onItemClick(AdapterView<?> parent, View view,
                                int position, long id) {

            //color change
            //selected item colored

            for(int i=0; i<stList.getAdapter().getCount();i++)
            {
                stList.getChildAt(i).setBackgroundColor(Color.TRANSPARENT);
            }

            parent.getChildAt(position).setBackgroundColor(Color.GRAY);

    });
1
Miraj Hamid
View updateview;// above oncreate method
listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);


listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
         if (updateview != null) 
            updateview.setBackgroundColor(Color.TRANSPARENT);
         updateview = view;   

         view.setBackgroundColor(Color.CYAN);
     }
});
0
nandish

C'est très simple. Dans le constructeur de "OnItemClick", utilisez le paramètre "view", qui est le deuxième qui représente la vue des éléments listView ou GridView et devient la vue du nouvel élément créée par AdapterView. Donc, pour définir une nouvelle couleur UNIQUEMENT pour l'ARTICLE SELECTIONNE, procédez comme suit:

public void onItemClick(AdapterView<?> adapterView, View view, int i, long l){ //view is instead of the view like textView , ImageView, or whatever view.setBackgroundColor(Color.green); }

Si vous utilisez des codes différents pour définir une nouvelle couleur, vous devrez faire face à des comportements délicats tels que la couleur verte sera appliquée à l'élément non-cliqué.

Dans un ensemble ListView:

Android:choiceMode="singleChoice"

Créez un sélecteur pour un arrière-plan (drawable/selector_gray.xml):

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

Ajouter un élément pour une liste:

<?xml version="1.0" encoding="utf-8"?>
<TextView
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:tools="http://schemas.Android.com/tools"
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    Android:gravity="center"
    Android:padding="5dp"
    Android:background="@drawable/selector_gray"
    Android:textColor="@color/colorPrimary"
    tools:text="Your text" />

Dans un ViewHolder, vous pouvez gonfler cet article.

0
CoolMind