I have a button in my OptionMenu which when touched will open a popup menu of items which are fetched at run time and added programmatically (so can't use hard coded xml menu items). I want to highlight a subset of these items according to their value, I used what is suggested here: How to customize item background and item text color inside NavigationView? to try and get the items to be colored differently. However, all of the items are colored the same despite the isChecked()
value being different.
Here is a small working example of the issue:
MainActivity.java
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater menuInflater = getMenuInflater();
menuInflater.inflate(R.menu.actionbar_menu, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
switch(id) {
case R.id.action_bar_button:{
showMenu();
return true;
}
}
return super.onOptionsItemSelected(item);
}
private void showMenu() {
View v = findViewById(R.id.action_bar_button);
Context wrapper = new ContextThemeWrapper(this, R.style.MyPopupMenu);
PopupMenu popupMenu = new PopupMenu(wrapper, v);
//Sample items to demonstrate the issue. I want the background to be red if false, blue if true
Map<String, Boolean> list = new HashMap<>();
list.put("Item 1", true);
list.put("Item 2", false);
list.put("Item 3", true);
for(Map.Entry<String, Boolean> entry : list.entrySet()){
String msg = entry.getKey();
MenuItem item = popupMenu.getMenu().add(msg).setCheckable(true).setChecked(entry.getValue());
System.out.println(item.getTitle() + ": " + item.isChecked());
}
popupMenu.show();
}
styles.xml contains:
<style name="MyPopupMenu" parent="Widget.AppCompat.PopupMenu">
<item name="android:itemBackground">@drawable/menu_item_background</item>
</style>
actionbar_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/action_bar_button"
android:title="List"
android:icon="@drawable/ic_launcher_foreground"
app:showAsAction="always" />
</menu>
colors.xml contains:
<color name="red">#ff0000</color>
<color name="blue">#0000FF</color>
And the menu_item_background.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@color/blue" android:state_checked="true"/>
<item android:drawable="@color/red" android:state_checked="false"/>
</selector>
However, when I run this I get the following:
As you can see although the isChecked
state of Item 1 and 3 is true, they still appear red. The logcat output confirms this.
As an experiment I changed the menu_item_background.xml
to use the android:state_enabled
instead of checked and it works as expected:
What's going on here? Why doesn't this work with android:state_checked
?
Thanks for your help.