32

我创建了两个具有唯一 ID 的组(我需要一个分隔符),并且它们都checkableBehavior设置为single。这允许一次检查来自不同组的多个项目,而这正是我想要避免的。我希望在所有组中最多检查一项。

由于我还没有找到在 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;
                }
            });

menuItem.setCheckable(true)注意:您可以android:checkable="true"为 XML 中的每个项目设置而不是调用。

@Moinkhan 的解决方案应该也可以工作(谢谢,赞成),但我不想在每次选择新位置时循环遍历菜单项。

于 2015-06-11T13:50:23.203 回答
11

实际上,您不需要单独的并行组作为分隔符。您可以将所有内容放在一个组中,并在其中放置子菜单(有标题)或子组(无标题)。这些子菜单和子组将有分隔符。这样,可检查的行为就可以在没有解决方法的情况下工作。 (仅供参考:这是在设计支持库 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 回答
7

无需删除checkableBehavior="single",只需使用

navigationView.setCheckedItem(item.getItemId());

而不是item.setChecked(true).

于 2016-02-28T16:09:17.997 回答
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)不起作用。仅仅因为从菜单列表中应该有一个必须检查的项目。因此,您只能在选择另一个项目时取消选中它。如果您单击所选项目,则导航视图将永远不会取消选中它。只是因为我已经解释了这个场景。

于 2015-06-11T06:11:55.423 回答
3

实现中似乎有一个失效错误NavigationView,但你不需要使用setCheckable(),你只需要NavigationView在调用后失效setChecked(false),如下所示:

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

但是菜单组不能有checkableBehavior="single",因为在独占模式下调用组中的setChecked(boolean)aMenuItem会将该项目设置为选中,无论您传递 true 还是 false。所以为了setChecked(false)工作,你必须checkableBehavior="single"从你的菜单定义中删除。

我在这里创建了一个关于此的问题:https ://code.google.com/p/android/issues/detail?id=178709

于 2015-07-03T23:40:24.530 回答
1

这是我在这里发布的一个简单而甜蜜的解决方案:)

制作不同的组确实在它们之间产生了分隔但是会在导航抽屉中产生两个选中项目的问题。

我处理这个问题的一个简单方法是:

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