如何在导航视图中取消选中选中的项目?

时间:2016-03-17 03:15:34

标签: android navigationview android-navigationview

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

12 个答案:

答案 0 :(得分:47)

这将取消选中项目:

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

答案 1 :(得分:28)

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

  1. 选择菜单项1(使用NavigationView#setCheckedItem
  2. 根据@ arsent的解决方案取消选择所有项目
  3. 再次选择菜单项1(使用NavigationView#setCheckedItem
  4. 在这种情况下,第1项不会被标记为已选中。这是因为导航视图在内部跟踪在步骤1中设置的先前选择的项目,在步骤2中没有改变,并且它只是跳过步骤3,因为先前选择的项目与步骤3相同我们现在正在选择。

    我的建议(以及另一种解决方案)避免这种情况只是拥有一个虚拟的隐形物品,并且只要您想要取消全部选择,就可以使用NavigationView#setCheckedItem选择该项目,如此

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

    取消选择所有只做

    mNavigationView.setCheckedItem(R.id.menu_none);
    

答案 2 :(得分:17)

要取消选中包含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());

答案 3 :(得分:6)

只是让你的物品不可检查

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

答案 4 :(得分:2)

引用@Codeversed,有&#34; 无需循环添加开销菜单项!&#34;。但是,不需要创建多个组(在这种情况下,他正在创建@+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>

答案 5 :(得分:1)

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解决方案。

答案 6 :(得分:1)

我想像我这样的人会像这样使用这些方法

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_today后,尝试检查R.id.nav_calendar,(顺便说一下:checkableBehavior="single"),遗憾的是它不起作用。

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

这就是为什么你使用的任何方法似乎永远不会起作用的原因。这是工作,但要立即覆盖。

答案 7 :(得分:0)

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

 <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 :(得分:0)

我结合了@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#和work的,但你可以很容易地转换为java

答案 9 :(得分:0)

要在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;
                });

p.s。在我的情况下,App.getHandler()返回了Handler个UI线程Lopper实例

答案 10 :(得分:0)

我不得不结合使用这里提到的所有解决方案。就我而言,我想在单击项目时打开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 :(得分:0)

@arsent的答案是正确的,但setCheckable(false)取消选中所有项目,这防止将来再次检查项目。

只需使用setChecked(false)

import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.drawerlayout.widget.DrawerLayout
import com.example.tender.R
import com.example.tender.databinding.FragmentAvailableTenderBinding
import com.example.tender.databinding.FragmentLoginBinding
import androidx.navigation.fragment.findNavController
import androidx.navigation.ui.NavigationUI

/**
 * A simple [Fragment] subclass.
 */
class AvailableTenderFragment : Fragment() {

    private lateinit var drawerLayout: DrawerLayout

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {

        val binding = FragmentAvailableTenderBinding.inflate(inflater)

        drawerLayout = binding.drawerLayout

        **val navController = this.findNavController(R.id.nav_host_fragment)**

        **NavigationUI.setupActionBarWithNavController(this, navController, drawerLayout)**

        NavigationUI.setupWithNavController(binding.navView, navController)

        binding.root

    }
}