19

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'sisChecked()プロパティが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

5 に答える 5

38

http://developer.android.com/guide/topics/ui/menus.htmlの公式ドキュメントによると

注:(オプションメニューからの)アイコンメニューのメニュー項目は、チェックボックスまたはラジオボタンを表示できません。アイコンメニューの項目をチェック可能にする場合は、状態が変化するたびにアイコンやテキストを入れ替えて、チェック状態を手動で指定する必要があります。

それが役に立てば幸い。

于 2011-08-18T10:42:19.820 に答える
12

それでも動作(チェック済み、チェックなし)をxmlドローアブルで定義したい場合は、これを実現する1つの方法です。

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());
}
于 2014-01-21T13:55:32.713 に答える
6

もう少し簡単な方法(xml-statesファイルなし):

configChecked = !configChecked;
item.setChecked(configChecked);
item.setIcon(configChecked ? R.drawable.check_on : R.drawable.check_off);
于 2014-11-14T13:30:28.450 に答える
3

質問は少し古いですが、私は最近この問題に遭遇しました。

いくつかの分析の結果、メニュー項目のチェックされた状態がドローアブルに適切に伝播されていないことがわかりました。これが私が(Kotlinで)思いついた解決策です。

menuItem(質問からのように)状態リストのドローアブルを使用していることを確認してbtn_star.xmlから、ドローアブルラッパークラスを作成します。

/** Fixes checked state being ignored by injecting checked state directly into drawable */
class CheckDrawableWrapper(val menuItem: MenuItem) : DrawableWrapper(menuItem.icon) {
    // inject checked state into drawable state set
    override fun setState(stateSet: IntArray) = super.setState(
        if (menuItem.isChecked) stateSet + android.R.attr.state_checked else stateSet
    )
}

/** Wrap icon drawable with [CheckDrawableWrapper]. */
fun MenuItem.fixCheckStateOnIcon() = apply { icon = CheckDrawableWrapper(this) }

最後のステップは、ドローアブルのメニュー項目をラップされたドローアブルに置き換えることです。

override fun onCreateOptionsMenu(menu: Menu) : Boolean{
    menuInflater.inflate(R.menu.menu_main, menu)
    menu.findItem(R.id.menu_starred).fixCheckStateOnIcon()
    /** ...  */
    return true
}

その後、メニュー項目のチェック状態を変更するときに何もする必要はありません。アイコンは自己認識し、チェック状態が変更されるたびに反応する必要があります。

于 2019-09-02T11:16:42.293 に答える
0
<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);
}
于 2019-05-20T05:48:01.927 に答える