Проверенное состояние MenuItem неправильно отображается его значком - PullRequest
16 голосов
/ 13 июля 2011

У меня MenuItem определен следующим образом:

<?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>

и btn_star.xml определены следующим образом:

<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>

Когда я создаю меню параметров с помощью этого, значокникогда не показывается в проверенном состоянии, даже если свойство MenuItem isChecked() имеет значение true.

Я использую элемент управления ActionBarSherlock , однако я получаю то же самоерезультат, если я просто создаю обычное меню параметров и вызываю setChecked(true).Он по-прежнему отображает btn_star_off, который можно рисовать, независимо от того, отмечен ли элемент.

Метод onOptionsItemSelected() вызывается правильно, и я могу успешно изменить проверенное свойство:

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

Установка точки останова здесь показывает, что свойство isChecked изменяется, но сам значокне обновляется, чтобы отразить правильное состояние.

Есть что-то, что я здесь упускаю?Я делаю это неправильно?Я не могу понять, почему это не будет работать правильно.

Ответы [ 4 ]

35 голосов
/ 18 августа 2011

Согласно официальному документу на http://developer.android.com/guide/topics/ui/menus.html

Примечание: пункты меню в меню значков (из меню параметров) не могут отобразить флажок или переключатель. Если вы решили сделать элементы в Значок меню можно проверить, Вы должны вручную указать проверенное состояние с помощью меняя значок и / или текст каждый раз, когда изменяется состояние.

Надеюсь, это поможет.

11 голосов
/ 21 января 2014

Если вы все еще хотите, чтобы поведение (проверенное, не проверенное) было определено в xml-файле, это можно сделать одним из следующих способов:

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());
}
5 голосов
/ 14 ноября 2014

Немного проще (без файла xml-состояний):

configChecked = !configChecked;
item.setChecked(configChecked);
item.setIcon(configChecked ? R.drawable.check_on : R.drawable.check_off);
0 голосов
/ 20 мая 2019
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item android:id="@+id/fav"
        android:title=""
        app:showAsAction="ifRoom"
        android:orderInCategory="1"
        android:icon="@drawable/ic_favorite_black_unselectd"
        android:checked="false" />
    <item android:id="@+id/share"
        android:title=""
        app:showAsAction="ifRoom"
        android:orderInCategory="2"
        android:icon="@drawable/ic_share_black" />
</menu>

//and in java...

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.fav:
            boolean mState = !item.isChecked();
            item.setChecked(mState);
            item.setIcon(mState ? getResources().getDrawable(R.drawable.ic_favorite_black_selected) : getResources().getDrawable(R.drawable.ic_favorite_black_unselectd));
            Toast.makeText(this, "" + item.isChecked(), Toast.LENGTH_SHORT).show();
            return true;
        case R.id.share:
            return true;
    }
    return super.onOptionsItemSelected(item);
}
...