J'ai la disposition de menu suivante dans mon Android:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:Android="http://schemas.Android.com/apk/res/Android">
<item Android:id="@+id/item1"
Android:titleCondensed="Options"
Android:title="Highlight Options"
Android:icon="@Android:drawable/ic_menu_preferences" />
<item Android:id="@+id/item2"
Android:titleCondensed="Persist"
Android:title="Persist"
Android:icon="@Android:drawable/ic_menu_preferences"
Android:checkable="true" />
</menu>
Mon problème est que le deuxième élément du menu ne semble pas être "vérifiable" lorsque j'exécute mon application dans l'émulateur Android. Il devrait y avoir une coche verte à propos de l'élément, non? Pour indiquer que son vérifiable.
Est-ce que je fais quelque chose de mal?
La mise en page semble correcte. Mais vous devez cocher et décocher l'élément de menu dans le code.
De la documentation :
Lorsqu'un élément vérifiable est sélectionné, le système appelle votre méthode de rappel sélectionnée par élément respective (telle que
onOptionsItemSelected()
). C'est ici que vous devez définir l'état de la case à cocher, car une case à cocher ou un bouton radio ne change pas automatiquement son état. Vous pouvez interroger l'état actuel de l'élément (tel qu'il était avant que l'utilisateur ne le sélectionne) avecisChecked()
puis définir l'état vérifié avecsetChecked()
.
Enveloppez les item
s dans un élément group
, comme ceci:
<menu xmlns:Android="http://schemas.Android.com/apk/res/Android">
<group Android:checkableBehavior="all">
<item Android:id="@+id/item1"
Android:titleCondensed="Options"
Android:title="Highlight Options"
Android:icon="@Android:drawable/ic_menu_preferences">
</item>
<item Android:id="@+id/item2"
Android:titleCondensed="Persist"
Android:title="Persist"
Android:icon="@Android:drawable/ic_menu_preferences"
Android:checkable="true">
</item>
</group>
</menu>
Depuis les documents Android :
L'attribut Android: checkableBehavior accepte soit:
single - Un seul élément du groupe peut être vérifié (boutons radio)
all - Tous les éléments peuvent être cochés (cases à cocher)
aucun - Aucun élément n'est vérifiable
Vous pouvez créer un élément de menu vérifiable en définissant actionViewClass
sur un widget vérifiable comme Android.widget.CheckBox
res/menu/menu_with_checkable_menu_item.xml
<menu xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:app="http://schemas.Android.com/apk/res-auto">
<item
Android:id="@+id/action_favorite"
Android:checkable="true"
Android:title="@string/action_favorite"
app:actionViewClass="Android.widget.CheckBox"
app:showAsAction="ifRoom|withText" />
</menu>
Et vous pouvez même le styliser pour qu'il devienne une étoile à cocher si vous définissez actionLayout
sur une mise en page avec un style Android.widget.CheckBox
res/layout /action_layout_styled_checkbox.xml
<CheckBox xmlns:Android="http://schemas.Android.com/apk/res/Android"
style="?android:attr/starStyle"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content" />
res/menu/menu_with_checkable_star_menu_item.xml
<menu xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:app="http://schemas.Android.com/apk/res-auto">
<item
Android:id="@+id/action_favorites"
Android:checkable="true"
Android:title="@string/action_favorites"
app:actionLayout="@layout/action_layout_styled_checkbox"
app:showAsAction="ifRoom|withText" />
</menu>
Pour définir la valeur
menuItem.setChecked(true/false);
Pour obtenir la valeur
menuItem.isChecked()
Cast MenuItem vers CheckBox
CheckBox checkBox= (CheckBox) menuItem.getActionView();
Pour ajouter des éléments de menu par programme,
@Override
public boolean onCreateOptionsMenu(Menu menu) {
menu.add("Item1").setActionView(R.layout.action_layout_checkbox).setCheckable(true);
return super.onCreateOptionsMenu(menu);
}
res/layout /action_layout_checkbox.xml
<CheckBox xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content" />
Cela peut dépendre du thème, mais mon menu n'affichait aucune case à cocher. J'ai trouvé ceci :
Remarque: les éléments de menu du menu d'icônes ne peuvent pas afficher une case à cocher ou un bouton radio. Si vous choisissez de rendre les éléments du menu d'icônes vérifiables, vous devez alors indiquer personnellement l'état en échangeant l'icône et/ou le texte chaque fois que l'état change entre activé et désactivé.
LIRE CECI
Comme on l'a dit, la "vérification manuelle" n'est que la pointe de l'iceberg. Il fait clignoter le menu si rapidement que les utilisateurs ne voient rien se produire et il est très contre-intuitif, frustrant et efficace. Le REAL TASK
(donc) permet à l'événement de la case à cocher d'être digéré par l'esprit des utilisateurs.
Bonne nouvelle: ceci peut être fait et cela fonctionne et c'est comme ça que vous le faites. @TouchBoarder l'a mieux fait, je vais donc copier son code. puis développez-le.
l'idée est de détecter si la case est cochée, puis (et seulement si celle-ci est sélectionnée) de supprimer légèrement la suppression du menu, d'ajouter une minuterie pendant 500 ms puis de fermer le menu, cela donne à l'animation "tick" du temps de la case à cocher et crée la bonne "sensation"
<menu xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:app="http://schemas.Android.com/apk/res-auto">
<item
Android:id="@+id/action_favorite"
Android:checkable="true"
Android:title="@string/action_favorite"
app:actionViewClass="Android.widget.CheckBox"
app:showAsAction="ifRoom|withText" />
</menu>
alors vous faites cette méthode comme d'habitude, mais vous vous assurez d'ajouter tous ces bumpf supplémentaires
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the bottom bar and the top bar (weird)
BottomAppBar bottomBar = findViewById(R.id.bottom_app_bar_help);
Menu bottomMenu = bottomBar.getMenu();
getMenuInflater().inflate(R.menu.bottom_nav_menu, bottomMenu);
for (int i = 0; i < bottomMenu.size(); i++) {
bottomMenu.getItem(i).setOnMenuItemClickListener(item -> {
if (item.getItemId()==R.id.action_favorite){
item.setChecked(!item.isChecked());
// Keep the popup menu open
item.setShowAsAction(MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW);
item.setActionView(new View(frmMain.this));
item.setOnActionExpandListener(new MenuItem.OnActionExpandListener() {
@Override
public boolean onMenuItemActionExpand(MenuItem item) {
final Handler handler = new Handler();
handler.postDelayed(() -> bottomMenu.close(), 500);
return false;
}
@Override
public boolean onMenuItemActionCollapse(MenuItem item) {
final Handler handler = new Handler();
handler.postDelayed(() -> bottomMenu.close(), 500);
return false;
}
});
return false;
}
else {
return onOptionsItemSelected(item);
}
});
}
return true;
}
les autres événements du menu sont ici
public boolean onOptionsItemSelected(MenuItem item) {
// Bottom Bar item click
try {
switch (item.getItemId()) {
case R.id.mnuExit:
MenuClick(ClickType.LOGOUT);
return true;
case R.id.mnuList:
MenuClick(ClickType.LIST);
return true;
default:
return super.onOptionsItemSelected(item);
}
} catch (Exception e) {
e.printStackTrace();
}
return super.onOptionsItemSelected(item);
}