32

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

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

4

6 に答える 6

39

これが解決策です。

ステップ 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;
                }
            });

注: を呼び出す代わりに、XML で各項目をmenuItem.setCheckable(true)設定できます。android:checkable="true"

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

于 2015-06-11T13:50:23.203 に答える
11

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

仕切りのあるメニュー

<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());
    ...
}
于 2015-11-23T17:32:28.260 に答える
4

解決策を見つけました..このスニペットコードを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)は機能しません。メニューのリストから、チェックする必要があるアイテムが1つあるはずだからです。したがって、別のアイテムを選択したときにのみチェックを外すことができます..そして、選択したアイテムをクリックすると、ナビゲーションビューは決してチェックを外しません。私が説明したシナリオだからです。

于 2015-06-11T06:11:55.423 に答える
1

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

異なるグループを作成すると、その間に仕切りができますが、ナビゲーション ドロワーに 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);

}

于 2015-07-11T14:26:50.513 に答える