web-dev-qa-db-ja.com

NavigationViewのすべてのグループにチェック可能な共有動作を設定するにはどうすればよいですか?

一意のIDを持つ2つのグループを作成し(仕切りが必要です)、両方ともcheckableBehaviorsingleに設定されています。これにより、異なるグループの複数のアイテムを一度にチェックできます。これはまさに避けようとしていることです。すべてのグループで、最大1つのアイテムをチェックしたいです。

XMLでこれを行う方法が見つからなかったため、onNavigationItemSelectedで簡単なロジックを実装して、前のメニュー項目のチェックを外そうとしました。

_if (previousItem != null)
   previousItem.setChecked(false);
currentItem.setChecked(true);
_

しかし、setChecked(false)メソッドは私にとっては決して機能しませんでした-アイテムはチェックされたままです。

これが私のサンプルコードです。

menu_navigation.xml:

_<menu xmlns:Android="http://schemas.Android.com/apk/res/Android">
<group
        Android:id="@+id/nav_group_1"
        Android:checkableBehavior="single">
    <item
            Android:id="@+id/nav_feed"
            Android:title="@string/feed"/>
    <item
            Android:id="@+id/nav_people"
            Android:title="@string/people"/>
</group>
<group
        Android:id="@+id/nav_group_2"
        Android:checkableBehavior="single">
    <item
            Android:id="@+id/nav_settings"
            Android:title="@string/settings"/>
    <item
            Android:id="@+id/nav_help_feedback"
            Android:title="@string/help_feedback"/>
    <item
            Android:id="@+id/nav_logout"
            Android:title="@string/logout"/>
</group>
_

NavigationItemSelectedListener:

_ mUiNavigationView.setNavigationItemSelectedListener(
                new NavigationView.OnNavigationItemSelectedListener() {
                    @Override
                    public boolean onNavigationItemSelected(MenuItem menuItem) {
                        if (previousItem != null)
                           previousItem.setChecked(false);
                        currentItem.setChecked(true);
                        //...
                        changeCurrentFragment(...);
                        return true;
                    }
                });
_

ヒントが必要です!ありがとう。

31
EyesClear

これが解決策です。

ステップ1:削除

_Android:checkableBehavior="single"
_

両方のグループから。

手順2:次のロジックをリスナーに追加します。

_mUiNavigationView.setNavigationItemSelectedListener(
            new NavigationView.OnNavigationItemSelectedListener() {
                @Override
                public boolean onNavigationItemSelected(MenuItem menuItem) {
                    menuItem.setCheckable(true);
                    menuItem.setChecked(true);
                    if (mPreviousMenuItem != null) {
                        mPreviousMenuItem.setChecked(false);
                    }
                    mPreviousMenuItem = menuItem;
                    //...
                    changeCurrentFragment(...);
                    return true;
                }
            });
_

注:menuItem.setCheckable(true)を呼び出す代わりに、XMLの各アイテムに_Android:checkable="true"_を設定できます。

@Moinkhanのソリューションも同様に機能するはずです(ありがとう、賛成です)が、新しい位置が選択されるたびにメニューの項目をループしたくありませんでした。

37
EyesClear

実際には、セパレーターのために別個の並列グループを必要としません。すべてを1つのグループに入れて、サブメニュー(タイトル付き)またはサブグループ(タイトルなし)を配置できます。これらのサブメニューとサブグループには区切り記号があります。これにより、回避策なしでチェック可能な動作が機能します。 (Fyi:これはDesign Support Lib 23.1.1にあります)

Menu with dividers

<group
    Android:id="@+id/drawer_group"
    Android:checkableBehavior="single">
    <item
        Android:id="@+id/nav_1"
        Android:title="Menu1" />
    <item
        Android:id="@+id/nav_2"
        Android:title="Menu2" />
    <item
        Android:id="@+id/nav_3"
        Android:title="Menu3" />
    <item
        Android:id="@+id/nav_4"
        Android:title="Menu4" />

    <item
        Android:id="@+id/drawer_submenu"
        Android:title="Subheader">
        <menu>
            <group Android:checkableBehavior="single">
                <item
                    Android:id="@+id/nav_sub1_1"
                    Android:title="Menu_Sub1_1" />
                <item
                    Android:id="@+id/nav_sub1_2"
                    Android:title="Menu_Sub1_2" />
            </group>
        </menu>
    </item>

    <group Android:id="@+id/drawer_subgroup">
        <item
            Android:id="@+id/nav_subgroup_item"
            Android:title="Menu_Sub2_2" />
    </group>
</group>

コードでは、私は単に次のことを行い、単一のチェックは期待どおりに動作します:

@Override
public boolean onNavigationItemSelected(MenuItem item) {
    mNavigationView.setCheckedItem(item.getItemId());
    ...
}
9
Till

_checkableBehavior="single"_を削除する必要はありません。使用するだけです

_navigationView.setCheckedItem(item.getItemId());
_

item.setChecked(true)の代わりに。

5
Jahid

解決策を見つけました。このスニペットコードをonNavigationItemSelectedメソッドに追加するだけです

@Override
    public boolean onNavigationItemSelected(MenuItem menuItem) {
    Menu m = navView.getMenu();
    for (int i=0;i<m.size();i++) {
        MenuItem mi = m.getItem(i);
        if (!(mi.getItemId() == menuItem.getItemId())) {
            mi.setCheckable(false);
        }
    }
    menuItem.setCheckable(true);
    menuItem.setChecked(true);
    return false;
}

それだけです。そして、はいsetChecked(false)動作していません。メニューのリストから、単一のアイテムをチェックする必要があるためです。そのため、別のアイテムを選択した場合にのみチェックを外すことができます。選択したアイテムをクリックすると、ナビゲーションビューでチェックが外されることはありません。シナリオを説明したからです。

4
Moinkhan

NavigationView実装には無効化のバグがあるようですが、setCheckable()を使用する必要はありません。setChecked(false)、 そのようです:

_    previousItem.setChecked(false);
    navigationView.invalidate();
_

ただし、メニューグループに_checkableBehavior="single"_があってはなりません。排他モードでは、グループ内のMenuItemsetChecked(boolean)を呼び出すと、trueまたはfalseを渡すかどうかのチェックとしてそのアイテムが設定されます。したがって、setChecked(false)が機能するためには、メニュー定義から_checkableBehavior="single"_を削除する必要があります。

これに関する問題をここで作成しました: https://code.google.com/p/Android/issues/detail?id=178709

3
Lorne Laliberte

ここに私が投稿したシンプルで甘い解決策があります here :)

異なるグループを作成すると、間に仕切りが作成されますが、ナビゲーションドロワーで2つのチェック項目の問題が発生します。

私がこれを処理する簡単な方法は次のとおりです。

 public boolean onNavigationItemSelected(final MenuItem menuItem) {

//if an item from extras group is clicked,refresh NAV_ITEMS_MAIN to remove previously checked item
if (menuItem.getGroupId() == NAV_ITEMS_EXTRA) {


    navigationView.getMenu().setGroupCheckable(NAV_ITEMS_MAIN, false, true);
    navigationView.getMenu().setGroupCheckable(NAV_ITEMS_EXTRA, true, true);
   }else{

    navigationView.getMenu().setGroupCheckable(NAV_ITEMS_MAIN, true, true);
    navigationView.getMenu().setGroupCheckable(NAV_ITEMS_EXTRA, false, true);


}
//Update highlighted item in the navigation menu
menuItem.setChecked(true);

}

1
Zorawar Sachdev