Как создать простой разделитель в новом навигационном экране?

Google представил NavigationView в библиотеке поддержки дизайна версии 22.2.0, с помощью которой вы можете легко создать ящик с помощью ресурса меню.

Как создать простую разделительную линию между двумя элементами? Группировка элементов не сработала. Создание секции вспомогательных элементов создает разделительную линию, но для этого требуется заголовок, который мне не нужен.

Любая помощь будет оценена.

Ответ 1

Все, что вам нужно сделать, это определить group с уникальным идентификатором, я проверил реализацию, если у группы есть другой идентификатор, он создаст разделитель.

Смотрите Android-источник:

См. реализацию в строке 517

Пример меню, создающий разделитель:

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

Ответ 2

создайте drawable 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 как app: 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"/>

и вот мы идем... скриншот

Ответ 3

Я думаю, что у меня есть еще лучшее решение проблемы с несколькими проверенными элементами. Используя мой способ, вам не нужно беспокоиться об изменении вашего кода при добавлении новых разделов в ваше меню. Мое меню выглядит так же, как принятое решение, написанное Джаредом, с разницей в использовании 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>

Проверяемое поведение "все" позволяет проверять/снимать отдельные элементы по желанию, независимо от того, из какой группы они принадлежат. Вам просто нужно сохранить последний проверенный элемент меню. 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;
}

Ответ 4

Создание разных групп, таких как ответ Nilesh, делает разделитель между ними создает проблему с двумя проверенными элементами в навигационном ящике.

Простым способом, которым я занимался, было следующее:

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

Ответ 5

Просто добавьте DeviderItemDecoration:

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

Он выглядит так:

введите описание изображения здесь

Ответ 6

Мне нужны разделители выше первого элемента и после последнего элемента. Используя решение @Nilesh, мне пришлось добавить фиктивные пункты меню и установить включенное значение false, которое было действительно грязным. Плюс, что делать, если я хочу делать другие интересные вещи в моем меню?

Я заметил, что NavigationView расширяет FrameLayout, поэтому вы можете поместить в него свой собственный контент так же, как и для FrameLayout. Затем я устанавливаю пустое меню xml, чтобы он отображал только мой собственный макет. Я понимаю, что это, вероятно, идет вразрез с тем путем, по которому Google хочет, чтобы мы принимали, но если вы хотите действительно настраиваемое меню, это простой способ сделать это.

<!--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>

И доступный

<?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>

изменить:

Вместо кнопок вы можете использовать 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>

Ответ 7

Я не уверен, что это исправлено в API 26 (Android 8), или это было возможно все время. Я по-прежнему новичок в программировании на Android. Однако я добавил родительские группы, как показано ниже. Тестирование на физическом телефоне Android 6,

  • У меня есть разделитель
  • Выбор любого элемента из nav_g1 или nav_g2 отменяет выбор других элементов.
  • Дополнительное дополнение не добавлено из-за вложенных групп.
  • Я не добавлял код 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>

Примечания

  • Как указано в this, каждая группа должна иметь уникальный идентификатор, чтобы показывать разделитель.
  • В соответствии с этим пространства ответов соответствуют спецификации дизайна материалов Google.
  • Требуется android:checkableBehavior="single" для родительской группы, поэтому проблема с несколькими выбранными пунктами меню в этом ответе (указанном в комментариях hungryghost) не происходит

И вот скриншот

Screenshot of the device screen

Ответ 8

Кредит должен пойти в Zorawar для решения, Извините за дублирование ответа, но не смог добавить в комментарий столько форматированного текста.

Решение Zorawar работает, код может быть улучшен как таковой:

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

Ответ 9

Nileh Answer is right, Кроме того, у него есть один недостаток двойной проверки.

<?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>

Таким образом, используя

Android: checkableBehavior = "сингл"

с уникальным идентификатором должен решить проблему

Ответ 10

Если вы хотите добавить divider динамически, вы можете просто добавить пустой SubMenu следующим образом:

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

это добавит разделитель.

просто обязательно перейдите в нужный индекс при использовании menu.getItem(int index)