如何在新的NavigationView中创build一个简单的分隔线?

Google在devise支持库22.2.0版中引入了NavigationView ,您可以使用菜单资源轻松创build抽屉。

我怎样才能在两个项目之间创build一个简单的分隔线? 分组项目不起作用。 创build一个子项目部分确实创build了一个分隔线,但它需要一个我不想要的标题。

任何帮助,将不胜感激。

所有你需要做的是定义一个唯一的ID group ,我已经检查了实现,如果组有不同的ID它会创build一个分频器。

查看Android来源:

请参阅行号517上的实施

示例菜单,创build分隔符:

 <menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" tools:context=".MainActivity"> <group android:id="@+id/grp1" android:checkableBehavior="single" > <item android:id="@+id/navigation_item_1" android:checked="true" android:icon="@drawable/ic_home" android:title="@string/navigation_item_1" /> </group> <group android:id="@+id/grp2" android:checkableBehavior="single" > <item android:id="@+id/navigation_item_2" android:icon="@drawable/ic_home" android:title="@string/navigation_item_2" /> </group> </menu> 

像这样创build一个可绘制的drawer_item_bg.xml

  <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item> <shape android:shape="rectangle" > <solid android:color="#F4F4F4" /> </shape> </item> <item android:top="-2dp" android:right="-2dp" android:left="-2dp"> <shape> <solid android:color="@android:color/transparent" /> <stroke android:width="1dp" android:color="#EAEAEA" /> </shape> <!-- android:dashGap="10px" android:dashWidth="10px" --> </item> </layer-list> 

并将其添加到NavigationView作为应用程序:itemBackground =“@ drawable / drawer_item_bg”

 <android.support.design.widget.NavigationView android:id="@+id/nav_view" android:layout_width="wrap_content" android:layout_height="match_parent" android:background="#F4F4F4" android:layout_gravity="start" android:fitsSystemWindows="false" app:menu="@menu/activity_main_drawer" app:itemBackground="@drawable/drawer_item_bg"/> 

在这里我们去… 截图

我想我有一个更好的解决scheme,多个检查项目的问题。 使用我的方式,您不必担心在向菜单中添加新节时更改代码。 我的菜单看起来就像Jared所写的接受的解决scheme,不同之处在于:在组中使用了:andoid:checkableBehavior =“ all

 <?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <group android:id="@+id/first_section" android:checkableBehavior="all"> <item android:id="@+id/frontpage" android:icon="@drawable/ic_action_home_24dp_light_blue" android:title="@string/drawer_frontpage" /> <item android:id="@+id/search" android:icon="@drawable/ic_search" android:title="@string/drawer_search" /> </group> <group android:id="@+id/second_section" android:checkableBehavior="all"> <item android:id="@+id/events" android:icon="@drawable/ic_maps_local_movies_24dp_light_blue" android:title="@string/drawer_events" /> </group> </menu> 

“全部”的checkableBehavior使得可以根据意愿检查/取消选中单个项目,而不pipe它们属于哪个组。 你只需要存储最后选中的菜单项。 java代码如下所示:

 private MenuItem activeMenuItem; @Override public boolean onNavigationItemSelected(MenuItem menuItem) { // Update selected/deselected MenuItems if (activeMenuItem != null) activeMenuItem.setChecked(false); activeMenuItem = menuItem; menuItem.setChecked(true); drawerLayout.closeDrawers(); return true; } 

让不同的组像Nilesh的答案确实在它们之间形成一个分隔符。但是在导航抽屉中创build了两个选中的项目的问题。

我如何处理这个简单的方法是:

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

简单添加DeviderItemDecoration:

 NavigationView navigationView = (NavigationView) findViewById(R.id.navigation); NavigationMenuView navMenuView = (NavigationMenuView) navigationView.getChildAt(0); navMenuView.addItemDecoration(new DividerItemDecoration(MainActivity.this,DividerItemDecoration.VERTICAL)); 

它看起来像这样:

在这里输入图像描述

我想要在第一个项目之上和最后一个项目之后的分隔符。 使用@Nilesh解决scheme,我不得不添加虚拟菜单项,并将其设置为false,这真的很脏。 另外如果我想在我的菜单中做其他很酷的东西呢?

我注意到NavigationView扩展FrameLayout,所以你可以把你自己的内容,就像你会为一个FrameLayout。 然后我设置一个空的菜单xml,以便它只显示我的自定义布局。 我明白,这可能违背了谷歌希望我们采取的path,但如果你想要一个真正的自定义菜单这是一个简单的方法来做到这一点。

 <!--Note: NavigationView extends FrameLayout so we can put whatever we want in it.--> <!--I don't set headerLayout since we can now put that in our custom content view--> <android.support.design.widget.NavigationView android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="start" android:fitsSystemWindows="true" app:menu="@menu/empty_menu"> <!--CUSTOM CONTENT--> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent"> <!-- CUSTOM HEADER --> <include android:id="@+id/vNavigationViewHeader" layout="@layout/navigation_view_header"/> <!--CUSTOM MENU--> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:layout_below="@+id/vNavigationViewHeader"> <View style="@style/NavigationViewLineSeperator"/> <Button android:text="Option 1"/> <View style="@style/NavigationViewLineSeperator"/> <Button android:text="Option 2"/> <View style="@style/NavigationViewLineSeperator"/> </LinearLayout> </RelativeLayout> </android.support.design.widget.NavigationView> 

这是风格

 <style name="NavigationViewLineSeperator"> <item name="android:background">@drawable/line_seperator</item> <item name="android:layout_width">match_parent</item> <item name="android:layout_height">1dp</item> </style> 

和drawable

 <?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <solid android:color="@color/white"/> <size android:width="100sp" android:height="1sp" /> </shape> 

和菜单

 <?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> </menu> 

编辑:

而不是button,您可以使用TextView与模仿原始菜单项的drawable:

  <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:text="@string/menu_support" android:drawableLeft="@drawable/menu_icon_support" style="@style/MainMenuText" /> // style.xml <style name="MainMenuText"> <item name="android:drawablePadding">12dp</item> <item name="android:padding">10dp</item> <item name="android:gravity">center_vertical</item> <item name="android:textColor">#fff</item> </style> 

信用应该去Zorawar的解决scheme,对不起复制的答案,但不能在评论中添加这么多格式的文本。

Zorawar的解决scheme是有效的,代码可以改进如下:

 public void onNavigationItemSelected(int groupId) { //if an item from extras group is clicked,refresh NAV_ITEMS_MAIN to remove previously checked item navigationView.getMenu().setGroupCheckable(NAV_ITEMS_MAIN, (groupId == NAV_ITEMS_MAIN), true); navigationView.getMenu().setGroupCheckable(NAV_ITEMS_EXTRA, (groupId == NAV_ITEMS_EXTRA), true); //Update highlighted item in the navigation menu menuItem.setChecked(true); } 

我不确定这是API 26 (Android 8)还是一直可能的。 我仍然是Android编程的小菜鸟。 不过,我添加了如下的父组。 在Android 6物理电话上testing,

  1. 我有分隔线
  2. nav_g1nav_g2select任何项目将取消select其他项目。
  3. 由于嵌套组没有添加额外的填充。
  4. 我没有添加任何Java代码给听众

菜单代码

 <?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <group android:checkableBehavior="single"> <group android:id="@+id/nav_g1" android:checkableBehavior="single"> <item android:id="@+id/nav_1" android:icon="@drawable/ic_menu_share" android:title="@string/nav_1"/> <item android:id="@+id/nav_2" android:icon="@drawable/ic_menu_share" android:title="@string/nav_2"/> </group> <group android:id="@+id/nav_g2" android:checkableBehavior="single"> <item android:id="@+id/nav_3" android:icon="@drawable/ic_menu_share" android:title="@string/nav_3"/> <item android:id="@+id/nav_4" android:icon="@drawable/ic_menu_share" android:title="@string/nav_4"/> </group> </group> <item android:title="Actions"> <menu> <item android:id="@+id/nav_7" android:icon="@drawable/ic_menu_share" android:title="@string/nav_7"/> <item android:id="@+id/nav_8" android:icon="@drawable/ic_menu_share" android:title="@string/nav_8"/> </menu> </item> </menu> 

笔记

  1. 正如在这个答案中提到的,每个组都需要有一个唯一的ID来显示分隔符。
  2. 根据这个答案空间匹配谷歌材料devise规格。
  3. 对于父组来说,需要有android:checkableBehavior="single" ,这样在这个答案中的多个select的菜单项(在hungryghost的注释中提到)的问题不会发生

这里是截图

设备屏幕的屏幕截图

尼列的答案是正确的,除了有一个双重检查的缺陷。

 <?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <group android:checkableBehavior="single" android:id="@+id/grp1"> <item android:id="@+id/nav_register_customer" android:icon="@drawable/ic_menu_camera" android:checkableBehavior="none" android:title="Register Customer" /> </group> <group android:id="@+id/grp2" android:checkableBehavior="single" > <item android:id="@+id/nav_slideshow" android:icon="@drawable/ic_menu_slideshow" android:checkableBehavior="none" android:title="Slideshow" /> </group> </menu> 

所以使用

机器人:checkableBehavior = “单”

用唯一的id来解决问题

如果你想dynamic添加分隔线,你可以添加一个空的SubMenu像这样:

 Menu menu = navigationView.getMenu(); menu.addSubMenu(" ").add(" "); 

这将添加一个分隔符。

只要确保在使用menu.getItem(int index)时传入正确的索引