web-dev-qa-db-ja.com

Android Checkable Menu Item

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>

私の問題は、Androidエミュレーターでアプリを実行したときに、2番目のメニュー項目が「チェック可能」に見えないことです。そのチェック可能。

私は何か間違っていますか?

59
Icemanind

レイアウトは正しく見えます。ただし、コード内のメニュー項目をオンまたはオフにする必要があります。

documentation から:

チェック可能なアイテムが選択されると、システムはそれぞれのアイテム選択コールバックメソッドを呼び出します( onOptionsItemSelected() など)。チェックボックスまたはラジオボタンは自動的に状態を変更しないため、ここでチェックボックスの状態を設定する必要があります。 isChecked() でアイテムの現在の状態(ユーザーが選択する前の状態)を照会し、チェック状態を設定できます。 with setChecked()

80
Sergey Glotov

次のように、itemsをgroup要素にラップします。

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

Android docs から:

Android:checkableBehavior属性は次のいずれかを受け入れます。

single-グループの1つの項目のみをチェックできます(ラジオボタン)

all-すべてのアイテムをチェックできます(チェックボックス)

none-チェック可能なアイテムはありません

32
Gabriel Negut

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

actionLayoutをスタイル付き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>

値を設定するには

menuItem.setChecked(true/false);

値を取得するには

menuItem.isChecked()

MenuItemをCheckBoxにキャスト

CheckBox checkBox= (CheckBox) menuItem.getActionView();
17
TouchBoarder

プログラムでメニュー項目を追加するには、

@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" />
0
Lins Louis

これはテーマに依存する場合がありますが、私のメニューにはチェックボックスが表示されませんでした。私は見つけました this

注:アイコンメニューのメニュー項目には、チェックボックスまたはラジオボタンを表示できません。アイコンメニューの項目をチェック可能にする場合は、状態がオンとオフの間で変わるたびにアイコンやテキストを交換することにより、個人的に状態を示す必要があります。

0
sham

これを読む

前述のように、「手動チェック」は氷山の一角にすぎません。それはメニューを非常に速くフラッシュし、ユーザーは何も起こりません、非常に直感的で、イライラし、効果的にくだらないものです。 REAL TASK(したがって)は、ユーザーの心がチェックボックスイベントをダイジェストできるようにします。

良いニュース:これは実行可能であり、動作します。これがあなたのやり方です。 @TouchBoarderが最高だったので、彼のコードをコピーします。その後、それを開発します。

チェックボックスがクリックされたかどうかを検出し、(選択された場合のみ)メニューの削除をわずかに抑制し、500msのタイマーを追加してメニューを閉じると、チェックボックスの「ティック」アニメーションが実行されます正しい「感触」を生み出します

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

その後、通常どおりこのメソッドを作成しますが、この余分なbumpfをすべて追加することを確認します

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

他のメニューイベントはこちら

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);
}
0
Mr Heelis