studio personalizado icono diseño cambiar android navigation-drawer android-support-library android-design-library navigationview

android - icono - navigation drawer personalizado



¿Cómo crear un divisor simple en el nuevo NavigationView? (13)

Además de las respuestas anteriores, si desea separadores decorativos pero no desea crear varios grupos debido a problemas de "comportamiento comprobable", puede asignar la misma identificación de grupo a todos sus grupos.

Ejemplo:

<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <group android:id="@+id/group_nav_common" <!-- New group id--> android:checkableBehavior="single"> <item android:id="@+id/menu_item_nav_home" android:icon="@drawable/ic_home_black_24dp" android:title="@string/nav_menu_main" /> <item android:id="@+id/menu_item_nav_articles" android:icon="@drawable/ic_art_track_black_24dp" android:title="@string/latest_news" /> <item android:id="@+id/menu_item_nav_group_categories" android:title="@string/nav_menu_sections"> <menu> <group android:id="@id/group_nav_common" <!-- Existing group id --> android:checkableBehavior="single"> <!-- Programmatically populated section --> </group> </menu> </item> <item android:id="@+id/menu_item_nav_group_sites" android:title="@string/nav_menu_sites"> <menu> <group android:id="@id/group_nav_common" <!-- Existing group id --> android:checkableBehavior="single"> <item android:id="@+id/menu_item_nav_select_site" android:icon="@drawable/ic_account_balance_black_24dp" android:title="@string/nav_menu_select_site" /> </group> </menu> </item> </group>

Google introdujo NavigationView en la Biblioteca de soporte de diseño versión 22.2.0 con la que puede crear un cajón muy fácilmente utilizando un recurso de menú.

¿Cómo puedo crear una línea divisoria simple entre dos elementos? Agrupar los artículos no funcionó. Crear una sección de elementos secundarios crea una línea divisoria, pero requiere un título, que no quiero.

Cualquier ayuda sería apreciada.


Creo que tengo una solución aún mejor para el problema de múltiples elementos marcados. Utilizando mi manera, no tiene que preocuparse por cambiar su código al agregar nuevas secciones a su menú. Mi menú se parece a la solución aceptada escrita por Jared, con la diferencia de usar andoid: checkableBehavior = " all " en los grupos:

<?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 de ''all'' hace posible marcar / desmarcar elementos individuales a voluntad, independientemente del grupo al que pertenecen. Solo tiene que almacenar el último elemento de menú marcado. El código java se ve así:

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


Hacer diferentes grupos, como la respuesta de Nilesh, hace un divisor en el medio Pero crea el problema de dos elementos marcados en el cajón de navegación.

Una forma simple de cómo manejé esto fue:

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


La respuesta de Nileh es correcta, excepto que tiene una falla de verificación doble.

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

Entonces usando

android: checkableBehavior = "single"

con identificación única resolverá el problema


No estoy seguro de si esto se solucionó en API 26 (Android 8) o si fue posible todo el tiempo. Todavía soy un novato en la programación de Android. Sin embargo, agregué grupos de padres como a continuación. Pruebas en teléfonos físicos con Android 6,

  1. Tengo el divisor
  2. Al seleccionar cualquier elemento de nav_g1 o nav_g2 se nav_g2 selección de otros elementos.
  3. No se agregó relleno adicional debido a grupos anidados.
  4. No agregué ningún código Java a los oyentes

Código de menú

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

Notas

  1. Como se menciona en this respuesta, cada grupo debe tener una identificación única para mostrar el divisor.
  2. Según this respuesta, los espacios coinciden con las especificaciones de diseño de material de Google.
  3. Tener android:checkableBehavior="single" para el grupo principal es obligatorio, por lo que el problema de varios elementos de menú seleccionados en this respuesta (mencionado en los comentarios de hungryghost) no ocurre

Y aquí está la captura de pantalla.


Puede agregar divisores fácilmente configurando el Fondo del elemento del menú a través de XML usando la 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"/>

Y use LayerDrawable como fondo. Conserva la superposición de ondas de diseño de material para clics.

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

El resultado:


Quería divisores sobre el primer artículo y después del último artículo. Usando la solución @Nilesh, tuve que agregar elementos de menú ficticios y configurar habilitado a falso, lo que me pareció realmente sucio. Además, ¿qué pasa si quiero hacer otras cosas interesantes en mi menú?

Noté que NavigationView extiende FrameLayout para que pueda poner su propio contenido como lo haría para un FrameLayout. Luego configuro un menú vacío xml para que solo muestre mi diseño personalizado. Entiendo que esto probablemente va en contra del camino que Google quiere que tomemos, pero si desea un menú verdaderamente personalizado, esta es una manera fácil de hacerlo.

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

Aqui esta el estilo

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

Y dibujable

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

Y el menu

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

editar:

En lugar de botones, puede usar TextView con dibujable que imita el aspecto de los elementos del menú original:

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


Si desea agregar un divisor dinámicamente , puede agregar un SubMenu vacío como este:

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

Esto agregará un divisor.

solo asegúrese de pasar el índice correcto cuando use menu.getItem(int index)


Si la respuesta seleccionada no funciona para usted, puede intentar agregar esto a onCreateOptionsMenu además de proporcionar la identificación única del grupo:

if (Build.VERSION.SDK_INT >= 28) { menu.setGroupDividerEnabled(true) }


Simple agregar DeviderItemDecoration:

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

Se ve así:


Todo lo que necesita hacer es definir un group con una ID única , he verificado la implementación si el grupo tiene diferentes ID''s, creará un divisor.

Ejemplo de menú, creando el separador:

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


cree un drawer_item_bg.xml dibujable como este,

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

y agréguelo a NavigationView como aplicación: 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"/>

y aquí vamos ... screenshot


El crédito debe ir a Zorawar por la solución. Perdón por duplicar la respuesta, pero no pudo agregar tanto texto formateado dentro de un comentario.

La solución de Zorawar funciona, el código podría mejorarse como tal:

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