web-dev-qa-db-fra.com

Mettre en surbrillance l'élément sélectionné dans ListView sur Android

J'ai créé une application qui fonctionne avec ListViews sous Android et je ne peux pas en faire de sorte que l'élément sélectionné (sélectionné) ait un arrière-plan différent. J'utilise CHOICE_MODE_SINGLE. Voici à quoi ressemble mon code:


Le ListView que j'utilise:
(inside layout.xml )

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

La mise en page TextView que j'utilise dans l'adaptateur:
( listItem.xml )

<TextView xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:id="@+id/listItem"
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    Android:textSize="23sp"
    Android:textStyle="bold" />

C'est ici que j'ajoute l'adaptateur:

mListAdapter = new ArrayAdapter<String>(this, R.layout.listItem, mList);
mListView = (ListView) findViewById(R.id.listView);
mListView.setAdapter(mAuthorAdapter);
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3) {
        String selected = mList.get(position);
        // ...
        mListView.setItemChecked(position, true);
    }
});

Je suis sûr que l'élément approprié est vérifié au clic, car lorsque j'appelle getCheckedItemPosition (), il renvoie la valeur appropriée.


Et maintenant, les deux choses que j'ai essayées pour mettre en surbrillance l'élément vérifié:


Sélecteur dessinable:
( selector_test.xml )

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

    <item Android:state_checked="true"><shape>
            <solid Android:color="@color/red" />
        </shape></item>
    <item Android:state_selected="true"><shape>
            <solid Android:color="@color/blue" />
        </shape></item>
    <item Android:state_pressed="true"><shape>
            <solid Android:color="@color/green" />
        </shape></item>

</selector>

Je l'ajoute à .xml avec:

Android:listSelector="@drawable/selector_test"

Fond dessinable:
( background_test.xml )

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

    <item Android:drawable="@color/red" Android:state_checked="true"/>
    <item Android:drawable="@color/blue" Android:state_selected="true"/>
    <item Android:drawable="@color/green"/>

</selector>

Je l'ajoute à .xml avec:

Android:background="@drawable/background_test"

J'ai essayé d'ajouter le sélecteur et l'arrière-plan à listView.xml et à listItem.xml, mais la seule chose qui change est la couleur d'arrière-plan par défaut et la couleur du sélecteur lorsque l'élément est enfoncé (ou maintenu).
Android: state_checked = "true" et Android: state_selected = "true" semblent ne rien faire.

Je peux changer l'arrière-plan en redéfinissant la méthode getView () dans ArrayAdapter et en y invoquant setBackgroundColor () si la vue est sélectionnée et que l'arrière-plan change, mais supprime également entièrement le sélecteur. De plus, je n'aime pas trop écraser les classes pour changer une ligne de code, surtout si la même chose peut être obtenue de manière différente.

Donc, ce que je demande, est-ce qu’il ya un moyen de mettre en surbrillance un élément coché dans ListView en ajoutant un sélecteur ou un fond pouvant être dessiné dessus, et je le fais simplement mal, ou devrais-je le faire fonctionner d’une autre manière .

Merci d'avance! :)

8
Velja

ajouter cette ligne dans onStart de votre activité

lv.setChoiceMode(ListView.CHOICE_MODE_SINGLE);

où lv est une instance de listView

puis substituez cette méthode et ajoutez-y les lignes suivantes.

 @Override
public void onListItemClick(ListView l, View v, int position, long id) {


    // Set the item as checked to be highlighted 
    lv.setItemChecked(position, true);
            v.setBackgroundColor(Color.BLUE);

        conversationAdapter.notifyDataSetChanged();

}

puis revenez à la couleur normale de l'arrière-plan de l'élément sélectionné précédemment et revenez à la méthode getView de votre adaptateur personnalisé.

8

Essaye ça:

listViewDay.setItemChecked(position, true);
listViewDay.setSelection(position);

listitem.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="40dp"
    Android:background="@drawable/list_day_selector" >

    <TextView
        Android:id="@+id/txtItemDay"
        Android:layout_width="fill_parent"
        Android:layout_height="fill_parent"
        Android:gravity="center_vertical|center_horizontal"
        Android:text="22"
        Android:textColor="@Android:color/white"
        Android:textSize="22sp" />

</LinearLayout>

list_selector.xml

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

    <item Android:drawable="@drawable/list_item_bg_normal" Android:state_activated="false"/>
    <item Android:drawable="@drawable/bg_with_left_arrow" Android:state_pressed="true"/>
    <item Android:drawable="@drawable/bg_with_left_arrow" Android:state_activated="true"/>

</selector>
5
Luc

Par programme, utilisez setSelector. Par exemple:

lv.setSelector(R.color.abc_background_cache_hint_selector_material_dark);
3

Définir l'état de l'élément dans le sélecteur comme ceci:

<selector xmlns:Android="http://schemas.Android.com/apk/res/Android">
    <item Android:state_activated="true"
        Android:color="@color/XXX/>
</selector>

Je ne sais pas pourquoi state_checked ne fonctionne pas. Au début, je pensais que ce devait être une Checkableview, puis j'ai essayé CheckedTextView. Ne fonctionne toujours pas.
Quoi qu'il en soit, state_activated résoudra le problème.

0
limmeng

Après quelques heures de pépin après l'autre (y compris le sélecteur laissant une bande sale), j'ai décidé de le faire moi-même:

class MyListAdapter extends ArrayAdapter<MyData> {
    // !!! access to the current selection
    int mSelected = 0;
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View v =  super.getView(position, convertView, parent);
        // !!! this is where the selected item is highlighted
        v.findViewById(R.id.selectionSign).setVisibility(position == mSelected ? View.VISIBLE : View.INVISIBLE);
        return v;
    }
    public CommandListAdapter(Context context, List<MyData> objects) {
        super(context, R.layout.mylistitem, R.id.mytext, objects);
    }
}

avec le OnItemClickListener:

        mMyListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                setSelectionPosNoUpd(position);
                update();
            }
        });

et les fonctions définies comme:

    void setSelectionPosNoUpd(int n) {
        mCommandListAdapter.mSelected = n;
        //update();
    }
    void update() {
        mListViewOfCommands.smoothScrollToPosition(getSelectionPos());
        mCommandListAdapter.notifyDataSetChanged();
    }

et l'élément de liste XML ( res/layout/mylistitem.xml ) est:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    >
    <LinearLayout
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        Android:orientation="vertical" >
        <TextView
        Android:layout_width="fill_parent"
        Android:layout_height="wrap_content"
        Android:id="@+id/mytext" 
        />
    </LinearLayout>
    <View
        Android:id="@+id/selectionSign"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        Android:background="#10ff5000"
        Android:visibility="invisible"
        />
</FrameLayout>

L'inconvénient est que, après avoir changé la sélection, je dois update () : il n'y a pas de moyen facile de décoiler la vue précédemment mise en surbrillance.

0