【问题标题】:How to uncheck checked items in Navigation View?如何取消选中导航视图中的选中项目?
【发布时间】:2016-03-17 03:15:33
【问题描述】:

我知道可以通过调用setCheckedItem() 或在onNavigationItemSelected 中返回真值来突出显示导航视图项以将该项显示为选定项,但是如何取消选中导航视图的选中项?

【问题讨论】:

    标签: android navigationview android-navigationview


    【解决方案1】:

    这将取消选中项目:

        int size = mNavigationView.getMenu().size();
        for (int i = 0; i < size; i++) {
            mNavigationView.getMenu().getItem(i).setCheckable(false);
        }
    

    【讨论】:

    • 我不知道使用你的代码后它给了我一个空白空间!
    • 就我而言,使用您的技术后,我检查了最后一项,但无法解决。请帮帮我...
    • @takmilul 确保你使用setChecked(false); 而不是true
    • 使用建议的代码,最后一个项目被选中。我通过用setCheckable(false)替换setChecked(false)解决了这个问题
    • setCheckable(false) 结合 setChecked(false) 用于我的案例中的每个项目。
    【解决方案2】:

    我看到了@arsent 解决方案并试了一下,它确实会做你想做的事,即取消选择所有项目......但是,我在以下场景中遇到了问题:

    1. 选择菜单项 1(使用 NavigationView#setCheckedItem
    2. 根据@arsent 的解决方案取消选择所有项目
    3. 再次选择菜单项 1(使用 NavigationView#setCheckedItem

    在这种情况下,项目 1 不会被标记为选中。这是因为导航视图在内部跟踪在第 1 步中设置的先前选择的项目,在第 2 步中不会更改,并且它只是跳过第 3 步,因为先前选择的项目与我们现在选择的项目相同。

    为了避免这种情况,我的建议(和替代解决方案)只是使用一个虚拟的不可见项目,并在您想取消全选时使用 NavigationView#setCheckedItem 选择该项目,就像这样

    <item
        android:id="@+id/menu_none"
        android:title=""
        android:visible="false"/>
    

    取消全选

    mNavigationView.setCheckedItem(R.id.menu_none);
    

    【讨论】:

    • 我发现我还必须使该菜单项 checkable="true" 才能工作,但是一旦我这样做了,那就太完美了!
    • 这甚至更快。聪明的解决方案!
    • 很遗憾SDK中没有内置类似的功能,我们必须破解它
    • 这么聪明的黑客!
    【解决方案3】:

    要取消选中所有MenuItems,包括SubMenu,您必须使用递归-

        private void unCheckAllMenuItems(@NonNull final Menu menu) {
            int size = menu.size();
            for (int i = 0; i < size; i++) {
                final MenuItem item = menu.getItem(i);
                if(item.hasSubMenu()) {
                    // Un check sub menu items
                    unCheckAllMenuItems(item.getSubMenu());
                } else {
                    item.setChecked(false);
                }
            }
        }
    

    调用上述方法取消选中所有项目,如下所示 -

    unCheckAllMenuItems(navigationView.getMenu());
    

    【讨论】:

      【解决方案4】:

      像这样让你的项目不可检查

      <item
          android:id="@+id/profile_item"
          android:checkable="false"
          android:title="@string/profile"/>
      

      【讨论】:

        【解决方案5】:

        引用@Codeversed,“无需循环菜单项并增加开销!”。但是,没有必要创建多个组(在这种情况下,他正在创建@+id/grp1@+id/grp2)来取消选中之前选中的项目。

        您可以使用android:checkableBehavior 为所有元素简单地添加一个组,如下所示:

        <group android:checkableBehavior="single">
            <item
                android:id="@+id/id1"
                android:checked="true"
                android:icon="@drawable/drawable1"
                android:title="@string/string1" />
        
            <item
                android:id="@+id/id2"
                android:icon="@drawable/drawable2"
                android:title="@string/string2" />
        </group>
        

        【讨论】:

          【解决方案6】:

          Joao 的解决方案并没有完全符合我的预期。这将导致我的导航上未选中的项目视图出现空白。

          只需确保将视图设置为消失即可:

          <item
              android:id="@+id/your_menu_item_id_to_hide"
              android:title=""
              android:visible="false"/>
          
          
          bottomNavigationView.getMenu().findItem(R.id.your_menu_item_id_to_hide).setChecked(true);
              bottomNavigationView.findViewById(R.id.your_menu_item_id_to_hide).setVisibility(View.GONE);
          

          在这种情况下不需要Arsent解决方案。

          【讨论】:

          • 我遇到了同样的问题,我已经解决了,但我现在不记得如何解决了。仔细检查布局文件中的 xml 参数
          • 啊,这是一个底部导航视图,它是最近的。我从未尝试过使用该组件的解决方案,但很高兴知道您设法对其进行了调整。
          【解决方案7】:

          您需要做的就是像这样围绕您的小组:

           <group>
              <group
                  android:id="@+id/grp1">
                  <item
                      android:id="@+id/nav_profile"
                      android:icon="@drawable/ic_account_circle_24dp"
                      android:title="@string/profile" />
              </group>
              <group
                  android:id="@+id/grp2">
                  <item
                      android:id="@+id/nav_settings"
                      android:icon="@drawable/ic_settings_24dp"
                      android:title="@string/settings" />
                  <item
                      android:id="@+id/nav_help"
                      android:icon="@drawable/topic_help"
                      android:title="@string/help_feedback" />
              </group>
          </group>
          

          无需增加开销循环菜单项!

          【讨论】:

            【解决方案8】:

            我猜像我这样的人就是这样使用这些方法的

            public boolean onNavigationItemSelected(@NonNull MenuItem item) {
                switch (item.getItemId()) {
                    case R.id.nav_today:
                        break;
                    case R.id.nav_calendar:
                       navigationView.getMenu().performIdentifierAction(R.id.nav_today, 0);
                       navigationView.getMenu().getItem(0).setChecked(true);//or
                       navigationView.setCheckedItem(R.id.nav_today);//or
                       drawerLayout.closeDrawers();
                       break;
                }
                return true;
            }
            

            点击R.id.nav_calendar后尝试检查R.id.nav_today,(顺便说一句:checkableBehavior="single"),不幸的是它不起作用。

            那是因为在您的代码navigationView.setCheckedItem(R.id.nav_today) 被调用之后,R.id.nav_today 将被立即检查,但在此之后,您对R.id.nav_calendar 的点击会自动检查。

            这就是为什么您使用的任何方法似乎都不起作用的原因。这是工作,但立即被覆盖。

            【讨论】:

              【解决方案9】:

              要在 NavigationItemSelectedListener 中取消选中它,我必须使用 post(到 UI 线程):

              App.getHandler().post(() -> menuItem.setChecked(false));
              

              完整示例:

               NavigationView navigationView = findViewById(R.id.nav_view);
                      navigationView.setNavigationItemSelectedListener(
                              menuItem -> {
                                  menuItem.setChecked(true);
              
                                  mDrawerLayout.closeDrawers();
              
                                  switch (menuItem.getItemId()) {
                                      ...
                                  }
              
                                  App.getHandler().post(() -> menuItem.setChecked(false));
              
                                  return true;
                              });
              

              附言在我的情况下,App.getHandler() 返回 UI Thread Lopper 的 Handler 实例

              【讨论】:

                【解决方案10】:

                我必须结合使用此处提到的所有解决方案。就我而言,我想在单击项目时打开一个 URL 意图(打开浏览器)。单击的项目应在单击后取消选中并重置为之前的项目。重要的是要了解,您不能在单击侦听器事件期间取消选中项目,因为已选中的状态将在之后处理。所以这是我在 Kotlin 中的解决方案:

                        val item = navigationView.menu.findItem(R.id.menu_item)
                        item.setOnMenuItemClickListener {
                
                            val oldItem = navigationView.checkedItem
                            rootView.postDelayed({ // you can use here any View to post a Runnable with a delay
                                navigationView.setCheckedItem(oldItem?.itemId ?: R.id.default_item)
                            }, 500)
                            browseURL("https://www.example.com")
                            true
                        }
                

                我将Navigation DrawerJetpack Navigation 结合使用。

                【讨论】:

                • 非常感谢,伙计,您节省了我的时间。
                【解决方案11】:

                我结合@arsent 和@Rahul 的答案并编写以下代码:

                 private void NavigationView_NavigationItemSelected(object sender, NavigationView.NavigationItemSelectedEventArgs e)
                        {
                            var size = navigationView.Menu.Size();
                            for (int i = 0; i < size; i++)
                            {
                               var item= navigationView.Menu.GetItem(i).SetChecked(false);
                                if (item.HasSubMenu)
                                {
                                    for (int j = 0; j < item.SubMenu.Size(); j++)
                                    {
                                        item.SubMenu.GetItem(j).SetChecked(false);
                                    }
                                }
                            }
                                e.MenuItem.SetChecked(true);
                
                            drawerLayout.CloseDrawers();
                
                        }
                

                以上代码适用于 xamarin c# 和工作,但您可以轻松转换为 java

                【讨论】:

                  【解决方案12】:

                  @arsent 的回答是正确的,但是 setCheckable(false) 取消选中所有项目,它会阻止将来检查项目。

                  只需使用 setChecked(false)

                    int size = mNavigationView.getMenu().size();
                  
                      for (int i = 0; i < size; i++) {
                          mNavigationView.getMenu().getItem(i).setChecked(false);
                      }
                  

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2013-08-10
                    • 1970-01-01
                    • 2015-12-03
                    • 1970-01-01
                    • 1970-01-01
                    • 2023-03-19
                    相关资源
                    最近更新 更多