web-dev-qa-db-fra.com

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

J'ai une XML avec deux ListView, une avec une liste de clients renseignée par une requête de sélection (lv_cli) et l'autre avec les détails du client sélectionné (lv_cli_det) . J'aimerais conserver le client sélectionné dans le lv_cli pendant que le lv_cli_det affiche les détails.

XML:

<ListView
    Android:id="@+id/cli_lista"
    Android:layout_width="512dp"
    Android:layout_height="wrap_content"
    Android:fadeScrollbars="false"
    >
</ListView>

<ListView
    Android:id="@+id/cli_lista_det"
    Android:layout_width="512dp"
    Android:layout_height="wrap_content"
    Android:layout_toRightOf="@+id/cli_lista"
    Android:fadeScrollbars="false" >
</ListView>

Java:

Cursor cursor = db.rawQuery("Select NrCl||';'||Nome From Clientes", null);
final ListView t = (ListView)findViewById(R.id.cli_lista);
ArrayAdapter<String> myarrayAdapter = new ArrayAdapter<String>(this, Android.R.layout.simple_expandable_list_item_1, listItems);
t.setAdapter(myarrayAdapter);

final ListView td = (ListView)findViewById(R.id.cli_lista_detalhe);
final ArrayAdapter<String> myarrayAdapter2 = new ArrayAdapter<String>(this, Android.R.layout.simple_expandable_list_item_1, listItems2);

t.setOnItemClickListener(new OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        String item = ((TextView)view).getText().toString();
        String[] strArray = item.split("\\;");

        cli.load(strArray[0].toString());
        td.setAdapter(myarrayAdapter2);
        listItems2.clear();
        listItems2.add("Nome: " + cli.getNome());
        listItems2.add("Morada: " + cli.getMorada());
        listItems2.add("Localidade: " + cli.getLoca());
        listItems2.add("Código Postal: " + cli.getCp());
        listItems2.add("Pais: " + cli.getPais());
        listItems2.add("Nif: " + cli.getNif());
        listItems2.add("Tel: " + cli.getTel());
        listItems2.add("Tlm: " + cli.getTlm());
        listItems2.add("Tipo Preço: " + cli.getTipoPvn());
        listItems2.add("Cond. Pagamento: " + cli.getCpg());
        listItems2.add("Obs: " + cli.getObs());
        td.setAdapter(myarrayAdapter2);
        myarrayAdapter2.notifyDataSetChanged(); 
    }
});
73
Celta

Pour conserver la couleur de l'élément listview lorsque vous appuyez dessus, incluez la ligne suivante dans la présentation de votre élément listview:

Android:background="@drawable/bg_key"

Définissez ensuite bg_key.xml dans le dossier drawable comme ceci:

<?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/pressed_color"/>
    <item
        Android:drawable="@color/default_color" />
</selector>

Enfin, incluez ceci dans votre ListViewonClickListener:

listView.setOnItemClickListener(new OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position,long arg3) {
        view.setSelected(true);
        ... // Anything
    }
});

De cette façon, un seul élément sera sélectionné par la couleur à la fois. Vous pouvez définir vos valeurs de couleur dans res/values/colors.xml avec quelque chose comme ceci:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="pressed_color">#4d90fe</color>
    <color name="default_color">#ffffff</color>
</resources>
126
Neoh

Trouvé le bon chemin. C'est très simple . En ressources, décrivez ce qui suit:

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

(ou vous pouvez spécifier un lien de ressource au lieu d'une valeur de couleur)

Programmatique:

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

le mode peut être l'un de ceux-ci: AbsListView.CHOICE_MODE_SINGLE, AbsListView.CHOICE_MODE_MULTIPLE, AbsListView.CHOICE_MODE_NONE (par défaut)

(AbsListView est l'ancêtre abstrait de la classe ListView)

P.S. les manipulations avec onItemClick et le changement de fond de vue sont en faillite, car une vue elle-même est un objet temporaire. Par conséquent, vous ne devez pas suivre une vue.

Si notre liste est suffisamment longue, les vues associées aux éléments sortis du défilement seront supprimées de la hiérarchie et seront recréées lorsque ces éléments s'afficheront à nouveau (avec des options d'affichage mises en cache, telles que l'arrière-plan). Ainsi, la vue que nous avons suivie n’est plus une vue réelle de l’élément. Changer son arrière-plan ne change en rien la vue réelle de l’élément. En conséquence, nous avons plusieurs éléments sélectionnés.

156
AJG
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {

            for (int j = 0; j < adapterView.getChildCount(); j++)
                adapterView.getChildAt(j).setBackgroundColor(Color.TRANSPARENT);

            // change the background color of the selected element
            view.setBackgroundColor(Color.LTGRAY);
});

Vous voudrez peut-être enregistrer l'élément sélectionné en cours dans une variable globale à l'aide de l'index i.

36
Chris623

De manière simpliste, si vous utilisez listview dans un xml, utilisez ces attributs dans votre listview,

Android:choiceMode="singleChoice"
Android:listSelector="#your color code"

si vous n'utilisez pas xml, par programme

listview.setChoiceMode(AbsListView.CHOICE_MODE_SINGLE);
listview.setSelector(Android.R.color.holo_blue_light);
13
Ashana.Jackol

Vous avez besoin d'un sélecteur comme ceci:

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

<!-- State when a row is being pressed, but hasn't yet been activated (finger down) -->
<item Android:drawable="@color/app_primary_color_light" Android:state_pressed="true" />

<!-- Used when the view is "activated". -->
<item Android:drawable="@color/app_primary_color" Android:state_activated="true" />

<!-- Default, "just hangin' out" state. -->
<item Android:drawable="@Android:color/transparent" /></selector>

Et ensuite, définissez Android:choiceMode="singleChoice" sur votre ListView.

4

De l'exemple d'Avinash Kumar Pankaj

View v;

puis à la méthode oncreate

v = new View(getActivity());

puis la méthode onlistitemclick j'ai écrit

public void onListItemClick(ListView listView, View view, int position,
       long id) {
   v.setBackgroundResource(0);
   view.setBackgroundResource(R.color.green);
   v = view;
}

Cela a fonctionné pour moi. Je vous remercie.

J'ai remplacé

v = new View(getActivity());

à

v = new View(this);

et le code a bien fonctionné.

Il est nécessaire que les fichiers XML 'couleurs' et 'bg_key' des exemples précédents aussi, ainsi que l'attribut ListView Android: background = "@ drawable/bg_key"

Mauro

2
Mauro Simoes

* s'il vous plaît assurez-vous qu'il n'y a pas d'ondulation à votre disposition racine du conteneur de vue liste

ajouter cette ligne à votre liste

Android:listSelector="@drawable/background_listview"

voici le fichier "background_listview.xml" 

<selector xmlns:Android="http://schemas.Android.com/apk/res/Android">
<item Android:drawable="@color/white_background" Android:state_pressed="true" />
<item Android:drawable="@color/primary_color" Android:state_focused="false" /></selector>

les couleurs utilisées dans le fichier background_listview.xml:

<color name="primary_color">#cc7e00</color>
<color name="white_background">#ffffffff</color>

après ces 

(l'élément sélectionné contient une couleur orange jusqu'à ce que vous cliquiez sur un autre élément)

2
ShahinFasihi

Pour ce faire, vous pouvez notamment suivre la position actuellement sélectionnée dans votre activité:

@Override
    public void onItemClick(AdapterView<?> arg0, View arg1, int position,
            long arg3) {
        currentPosition = position
        lv_cli.notifyDataSetChanged();
    }

Assurez-vous à présent d’attribuer un identifiant à la présentation parent (linearLayout, boxLayout, relativeLayout, .. comme vous le préférez) de votre élément de liste.

Ensuite, dans votre ListView, vous pouvez faire quelque chose comme ceci:

layoutBackground = (LinearLayout) convertView.findViewById(R.id.layout_background);

if (YourActivity.this.currentPosition == position) {
    layoutBackground.setBackgroundColor(YourActivity.this.getResources().getColor(R.color.hilight_color));
} else{
    layoutBackground.setBackgroundResource(R.drawable.list_item_drawable);
}

Fondamentalement, vous venez de définir la couleur hilight sur la mise en page en tant qu'arrière-plan lorsque celle-ci est égale à votre position actuellement sélectionnée . Notez comment je définis une ressource d'arrière-plan pouvant être dessinée lorsque l'élément n'est pas sélectionné. Cela pourrait être différent dans votre cas (puisque vous n'avez posté aucun code). Dans mon cas, ce dessinable est un sélecteur qui garantit que l'élément est bien éclairé lorsqu'il est enfoncé.

NOTE: Ce code simple n'utilise pas de détenteur de vue, mais j'ai vraiment recommande d'en utiliser un.

1

Utilisez l'identifiant à la place:

C'est la méthode la plus simple que vous puissiez gérer 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();
.....
0
Wasiun A. Khan