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,
- Tengo el divisor
-
Al seleccionar cualquier elemento de
nav_g1
onav_g2
senav_g2
selección de otros elementos. - No se agregó relleno adicional debido a grupos anidados.
-
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
- Como se menciona en this respuesta, cada grupo debe tener una identificación única para mostrar el divisor.
- Según this respuesta, los espacios coinciden con las especificaciones de diseño de material de Google.
-
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);
}