Как создать простой разделитель в новом NavigationView?
Google представил NavigationView в библиотеке поддержки дизайна версии 22.2.0, с помощью которой вы можете очень легко создать ящик, используя ресурс меню.
Как я могу создать простую разделительную линию между двумя элементами? Группировка элементов не сработала. Создание раздела подэлементов создает разделительную линию, но для этого требуется заголовок, который я не хочу.
любая помощь будет оценили.
11 ответов:
все, что вам нужно сделать, это определить
groupС уникальный идентификатор, Я проверил реализацию, если группа имеет разные идентификаторы, она создаст разделитель.пример меню, создающее разделитель:
<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>
создать 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"/>и вот мы идем... скриншот
простое добавление DeviderItemDecoration:
NavigationView navigationView = (NavigationView) findViewById(R.id.navigation); NavigationMenuView navMenuView = (NavigationMenuView) navigationView.getChildAt(0); navMenuView.addItemDecoration(new DividerItemDecoration(MainActivity.this,DividerItemDecoration.VERTICAL));Это выглядит так :
Я думаю, что у меня есть еще лучшее решение для проблемы нескольких проверенных элементов. Используя мой способ вам не придется беспокоиться о смене кода при добавлении новых разделов в меню. Мое меню выглядит так же, как принятое решение, написанное Джаредом, с разницей использования andoid:checkableBehavior="все" на группы:
<?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 'all' позволяет проверять / снимать флажки отдельных элементов по желанию, независимо от того, из какой группы они принадлежать. Вам просто нужно сохранить последний проверенный menuitem. В 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; }
создание различных групп, таких как ответ Нилеша, делает разделитель между ними, но создает проблему двух проверенных элементов в навигационном ящике.
простой способ, как я справился это:
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); }
Я хотел разделители над первым пунктом и после последнего пункта. Используя решение @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>и 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>edit:
вместо кнопок Вы можете использовать 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>
Я не уверен, что это исправлено в
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>Примечания
- как говорится в этой ответ каждая группа должна иметь уникальный идентификатор, чтобы показать разделитель.
- по состоянию на этой пробелы в ответе соответствуют спецификациям Google material design.
- С
android:checkableBehavior="single"для родительской группы требуется так проблема нескольких выбранных пунктов меню в этой ответ (упоминается в комментариях hungryghost) не происходита вот и скриншоты
вы можете легко добавить разделители, установив фон пункта меню через XML с помощью
app:itemBackground<android.support.design.widget.NavigationView android:id="@id/drawer_navigation_view" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="start" android:fitsSystemWindows="true" app:menu="@menu/all_navigation_menu" app:itemIconTint="@color/colorPrimary" app:itemBackground="@drawable/bg_drawer_item" android:background="@color/default_background"/>и использовать LayerDrawable в качестве фона. Он сохраняет наложение пульсаций материала для щелчков.
<?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item> <shape android:shape="rectangle"> <solid android:color="@color/white"/> </shape> </item> <item android:left="@dimen/activity_horizontal_margin"> <shape android:shape="rectangle"> <solid android:color="@color/divider"/> </shape> </item> <item android:bottom="1dp"> <shape android:shape="rectangle"> <solid android:color="@color/white"/> </shape> </item> </layer-list>результат:
кредит следует перейти к Зоравар для решения, извините за дублирование ответа, но не может добавить так много форматированного текста в комментариях.
Зоравар работает, код может быть улучшен, как например :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); }
ответ Ниле правильный, за исключением того, что он имеет один недостаток двойной проверки.
<?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= "single"
с уникальным идентификатором должен решить проблему
Если вы хотите добавить разделитель динамически, вы можете просто добавить пустое подменю, как это:
Menu menu = navigationView.getMenu(); menu.addSubMenu(" ").add(" ");это добавит разделитель.
просто не забудьте передать правильный индекс при использовании
menu.getItem(int index)



Comments