MenuItem's checked state is not shown correctl

2019-01-14 08:02发布

I have MenuItem defined this way:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/menu_starred"
        android:icon="@drawable/btn_star"
        android:title="@string/description_star"
        android:checkable="true"
        android:checked="true"
        android:orderInCategory="1"
        android:showAsAction="always" />
</menu>

and btn_star.xml defined this way:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item 
        android:state_checked="false" 
        android:drawable="@drawable/btn_star_off_normal" />
    <item 
        android:state_checked="true"
        android:drawable="@drawable/btn_star_on_normal" />
</selector>

When I create an options menu using this, however, the icon is never shown in its checked state, even if the MenuItem's isChecked() property is true.

I'm using the ActionBarSherlock control, however, I'm getting the same result if I simply create a normal options menu and call setChecked(true). It still displays the btn_star_off drawable regardless of the checked state of the item.

The onOptionsItemSelected() method is being called correctly, and I can successfully change the checked property:

@Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if(item.isCheckable()) {
            item.setChecked(!item.isChecked());
        }
        return super.onOptionsItemSelected(item);
}

Setting a breakpoint here shows the isChecked property being changed, but the icon itself is not updated to reflect the correct state.

Is there something I'm missing here? Am I doing this incorrectly? I can't figure out why this wouldn't be working correctly.

3条回答
淡お忘
2楼-- · 2019-01-14 08:26

If you still want to have the behavior (checked, not checked) defined in a xml drawable, this is one way you could accomplish this:

if (item.getItemId()==R.id.menu_item){
    item.setChecked(!item.isChecked());
    StateListDrawable stateListDrawable = (StateListDrawable) getResources().getDrawable(R.drawable.selector_drawable);
    int[] state = {item.isChecked()?android.R.attr.state_checked:android.R.attr.state_empty};
    stateListDrawable.setState(state);
    item.setIcon(stateListDrawable.getCurrent());
}
查看更多
Luminary・发光体
3楼-- · 2019-01-14 08:30

A bit simpler way (without xml-states file):

configChecked = !configChecked;
item.setChecked(configChecked);
item.setIcon(configChecked ? R.drawable.check_on : R.drawable.check_off);
查看更多
Evening l夕情丶
4楼-- · 2019-01-14 08:31

According to the official document at http://developer.android.com/guide/topics/ui/menus.html

Note: Menu items in the Icon Menu (from the Options Menu) cannot display a checkbox or radio button. If you choose to make items in the Icon Menu checkable, you must manually indicate the checked state by swapping the icon and/or text each time the state changes.

Hope it helps.

查看更多
登录 后发表回答