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! :)
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é.
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>
Par programme, utilisez setSelector. Par exemple:
lv.setSelector(R.color.abc_background_cache_hint_selector_material_dark);
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.
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.