web-dev-qa-db-fra.com

Comment mettre en évidence la ligne dans ListView dans Android?

Je dois mettre en surbrillance une ligne dans une ListView sélectionnée (pour montrer à l'utilisateur ce qu'il a choisi), donc ce n'est pas celle qui va être choisie, c'est celle qu'il a choisie auparavant.

J'ai déjà l'emplacement par:

ListView.setSelection(position);

Et maintenant, ce que je veux, c'est sélectionner cette ligne spécifique et la mettre en surbrillance.

Le code de la onCreate() dans l'activité qui contient la ListView:

public class CountryView extends Activity
{
    protected static final String LOG_TAG = null;
    /** Called when the activity is first created. */
    String[] lv_arr = {};

    ListAdapter adapter;
    TextView t;
    private ListView lvUsers;
    private ArrayList<Coun> mListUsers;
    String responce=null;
    public int d;
    int selectedListItem = -1;


    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.country);

        Intent data =getIntent();

        mListUsers = getCoun();
        lvUsers = (ListView) findViewById(R.id.counlistView);


        lvUsers.setAdapter(new ListAdapter(this, R.id.counlistView, mListUsers)); 


        selectedListItem=data.getExtras().getInt("PositionInList");

       lvUsers.setChoiceMode(ListView.CHOICE_MODE_SINGLE);



        lvUsers.setOnItemClickListener(new OnItemClickListener()
        {

            int positionItem;

            public void onItemClick(AdapterView<?> parent, View view,int position, long id)
            {
                Intent pongIntent = new Intent(getApplicationContext(),Trav.class);

                int counId=mListUsers.get(position).id;

                pongIntent.putExtra("response",mListUsers.get(position).p);
                pongIntent.putExtra("responseCounID",counId);

                //Put the position of the choose list inside extra
                positionItem=position;
                pongIntent.putExtra("PositionInListSet",positionItem);

                setResult(Activity.RESULT_OK,pongIntent);

                Log.i("CounID *******************************"," "+counId);
                finish();
            }
         });
    }
}
33
bifko

Puisque ListViews est défini par défaut sur un mode de sélection de NONE, en mode tactile, la méthode setSelection n'aura pas d'effet visuel. 

Pour conserver la sélection précédente/afficher visuellement une sélection explicite, vous devez d’abord définir le mode de choix de votre liste de visualisation de manière appropriée:

listview.setChoiceMode(ListView.CHOICE_MODE_SINGLE);

Il est utile de lire les documents API de ces méthodes: 

  • setSelection
void Android.widget.AdapterView.setSelection(int position)

Définit l'élément actuellement sélectionné. À soutenir les sous-classes d'accessibilité qui remplacer cette méthode doit invoquer le super la méthode super d'abord.

Paramètres :
position Index (à partir de 0) de la donnée à sélectionner.

  • setChoiceMode
void Android.widget.ListView.setChoiceMode(int choiceMode)

Définit le comportement de choix pour le Liste. Par défaut, les listes n'ont pas tout comportement de choix (CHOICE_MODE_NONE). En réglant le choiceMode à CHOICE_MODE_SINGLE, le La liste permet à un élément de figurer dans un état choisi. En réglant le choiceMode à CHOICE_MODE_MULTIPLE, la liste permet à n'importe quel nombre d'éléments de être choisi.

Paramètres :
choiceMode L'un desCHOICE_MODE_NONE, CHOICE_MODE_SINGLEouCHOICE_MODE_MULTIPLE

Au cas où cela ne suffirait pas (disons que vous souhaitez toujours afficher la dernière sélection différemment de la sélection actuelle), stockez le dernier élément sélectionné (une donnée qui remplit la ListAdapter) sous la forme lastSelectedItem et dans la méthode getView de votre adaptateur. une ressource d’arrière-plan différente du moteur de rendu si elle est égale à ceci lastSelectedItem.

Si votre dernière sélection ne s'actualise pas lors du changement de sélection, vous devez explicitement appeler la méthode notifyDataSetChanged sur votre instance d'adaptateur.

Mettre à jour
Puisque votre activité contenant la ListView est l'enfant d'une activité qui attend le résultat de celle-ci (basé sur la partie setResult(Activity.RESULT_OK,pongIntent);), l'idée initiale est correcte, la dernière position doit donc être transmise à l'intention lors du démarrage de l'activité:

selectedListItem = getIntent().getIntExtra("PositionInList", -1);
lvUsers.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
lvUsers.setSelection(selectedListItem);

La solution ListView.CHOICE_MODE_SINGLE fonctionnerait si vous restiez dans la même activité, mais que vous la finissiez à chaque itemClick (changement de sélection), c'est pourquoi les données supplémentaires devraient être transmises à la Intent de départ.

Vous pouvez également définir l'arrière-plan de l'élément précédemment sélectionné depuis votre adaptateur (comme indiqué ci-dessus), en remplaçant sa méthode getView:

lvUsers.setAdapter(new ArrayAdapter(this, R.id.counlistView, groups)
{
    @Override
    public View getView(int position, View convertView, ViewGroup parent)
    {
        final View renderer = super.getView(position, convertView, parent);
        if (position == selectedListItem)
        {
            //TODO: set the proper selection color here:
            renderer.setBackgroundResource(Android.R.color.darker_gray);
        }
        return renderer;
    }
});
37
rekaszeru

Juste:

  1. Définissez le mode de choix correct dans la vue Liste. setChoiceMode
  2. Définissez un arrière-plan pour prendre en charge l'état de sélection dans la présentation de votre article, par exemple: 

    Android:background="?android:attr/activatedBackgroundIndicator"
    

FYI: 

27
Daniel De León

Il est beaucoup plus facile d'implémenter cela dans vos fichiers de mise en page et de laisser Android s'occuper du reste ...

1) Assurez-vous que Android:choiceMode="" est défini sur votre mise en forme ListView (singleChoice, multipleChoice, etc.). Par défaut, il est défini sur none.

<ListView
    Android:id="@+id/invite_friends_fragment_contacts_list"
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    Android:choiceMode="multipleChoice"/> <!-- THIS LINE -->

2) Créez un fichier XML de sélecteur d'état et enregistrez-le dans votre dossier pouvant être dessiné. Dans cet exemple, nous l'appellerons state_selector.xml:

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

3) Dans votre mise en forme d'élément de liste, ajoutez le fichier state_selector.xml en tant qu'arrière-plan:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    Android:background="@drawable/state_selector">  <!-- THIS LINE -->

    <!-- ALL OF YOUR ELEMENTS WILL GO HERE (TextViews, ImageViews, etc) -->

</RelativeLayout>

Si vous utilisez multipleChoice, vous pouvez remplacer onItemClick()and définir/supprimer les éléments sélectionnés en conséquence . Android modifiera la couleur d'arrière-plan spécifiée dans votre fichier state_selector.xml.

14
Jabari

J'ai eu du mal à trouver une solution facile à cela, car de nombreux tutoriels et réponses contenaient des informations sur les sélections uniques via des boutons radio (qui reposaient largement sur RadioGroup). 

Mon problème était que je pouvais définir l'élément sur mon état "Surligné" mais ne pouvais ensuite pas réinitialiser la liste lorsque l'élément suivant était sélectionné. Voici ce que je suis venu avec:

listView.setOnItemClickListener(new ItemHighlighterListener ());

Avec cette classe:

private class ItemHighlighterListener implements OnItemClickListener{

    private View lastSelectedView = null;

    public void clearSelection()
    {
        if(lastSelectedView != null) lastSelectedView.setBackgroundColor(Android.R.color.transparent);
    }

    @Override
    public void onItemClick(AdapterView<?> arg0, View view, int arg2, long arg3) {
        clearSelection();
        lastSelectedView = view;
        view.setBackgroundDrawable(view.getContext().getResources().getDrawable(R.drawable.shape_selected_menu_item));
    }
}
9
Graeme

Je résous ce problème de la manière suivante: 1. définissez un lastClickId, lorsque vous cliquez sur l’élément dans listView, mettez à jour le lastClickId avec la valeur, puis le fond de la vue . l’élément que nous avons sélectionné hors de l’écran) et faites défiler en arrière, la surbrillance disparaît, car la méthode getView () est réexécutée dans votre adaptateur, nous devons donc effectuer la chose suivante . Dans votre adaptateur, modifiez l'arrière-plan de la méthode getView (), en voici le code:

private static int lastClickId = -1;
private OnItemClickListener listener = new OnItemClickListener() {

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position,
            long id) {
        if ((lastClickId != -1) && (lastClickId != position)) {
            parent.getChildAt(lastClickId).setBackgroundResource(
                    R.color.grey);
            view.setBackgroundResource(R.color.blue);
        }
        if (lastClickId == -1) {
            view.setBackgroundResource(R.color.blue);
        }
        lastClickId = position;

    }

};

public static int getCurrentSelectedItemId() {
    return lastClickId;
}

Adaptateur:

public View getView(int position, View convertView, ViewGroup parent) {
    // TODO Auto-generated method stub

    View view = mInflater.inflate(R.layout.Tweet_list_layout, null);
    // set selected item's background to blue
    if (position == MainUserFeedFragment.getCurrentSelectedItemId()) {
        view.setBackgroundResource(R.color.blue);
        }
    }
4
Xin Dou

Vous pouvez utiliser la transition. Suivez mon code car j'ai réussi à mettre en surbrillance un élément de liste spécifique par choix Disons que vous souhaitez mettre en évidence le premier élément pendant 5 secondes.

 if(position == 0){
                    viewHolderThubnail.relImage.setBackgroundResource(R.drawable.translate);
                    TransitionDrawable transition = (TransitionDrawable) viewHolderThubnail.relImage.getBackground();
                    transition.startTransition(1000);

                }else{

                    viewHolderThubnail.relImage.setBackgroundResource(R.color.white);
                }

translate.xml

<?xml version="1.0" encoding="UTF-8"?>
   <transition xmlns:Android="http://schemas.Android.com/apk/res/Android">
          <!-- The drawables used here can be solid colors, gradients, shapes, images, etc. -->
          <item Android:drawable="@drawable/new_state" />
          <item Android:drawable="@drawable/original_state" />
   </transition>

new_state.xml

<?xml version="1.0" encoding="UTF-8"?>
<shape   xmlns:Android="http://schemas.Android.com/apk/res/Android"
            Android:shape="rectangle">
    <solid Android:color="#92BCE7"/>
</shape>

original_state.xml

<?xml version="1.0" encoding="UTF-8"?>
<shape   xmlns:Android="http://schemas.Android.com/apk/res/Android"
            Android:shape="rectangle">
    <solid Android:color="#FFFFFF"/>
</shape>

Si vous avez compris ce code, ce qui est très simple, je dois le dire, l'élément de la liste de lecture situé en position zéro sera mis en évidence en couleur bleue pendant 5 secondes, puis il s'estompe lentement en couleur blanche.

1
Rahul Gupta

Pourquoi ne pas stocker les sélections dans un tableau, puis passez ce tableau dans le constructeur de l'adaptateur de tableau ListView, quelque chose comme myArrayAdapter(context,layoutID,dataArray,selectionArray)

ensuite, dans votre méthode getView pour le tableau, faites une vérification. Par exemple en pseudocode

if row was previously selected
    change background color
1
Faisal Abid

le plus simple OFF ALL

Voir updatedview = null;

        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {


           //these two lines of code means that only one item can be selected at a time
            if(updatedview != null) updatedview.setBackgroundColor(Color.TRANSPARENT);
            updatedview=view;


            Toast.makeText(getApplicationContext(), " " + str[position], Toast.LENGTH_LONG).show();



            view.setBackgroundColor(Color.CYAN);


        }
0
groot