web-dev-qa-db-fra.com

Comment créer un simple diviseur dans le nouveau NavigationView?

Google a introduit la NavigationView dans la version 22.2.0 de Design Support Library, qui permet de créer très facilement un tiroir à l'aide d'une ressource de menu.

Comment créer une simple ligne de séparation entre deux éléments? Le regroupement des éléments n'a pas fonctionné. La création d'une section de sous-éléments crée une ligne de séparation, mais elle nécessite un titre, ce que je ne souhaite pas.

Toute aide serait appréciée.

130
Longi

Tout ce que vous avez à faire est de définir une group avec un ID unique , j'ai vérifié l'implémentation si le groupe a des identifiants différents, il créera un diviseur.

Exemple de menu, créant le séparateur:

<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>
285
N J

Ajout simple DeviderItemDecoration:

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

Cela ressemble à ceci:

 enter image description here

16
SANAT

Je pense avoir une solution encore meilleure pour le problème des éléments cochés multiples. En utilisant ma manière, vous n’aurez plus à vous soucier de modifier votre code lorsque vous ajouterez de nouvelles sections à votre menu . Mon menu ressemble à la solution acceptée écrite par Jared, à la différence de l’utilisation de andoid: checkableBehavior = " all "sur les groupes:

<?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' permet de cocher/décocher des éléments individuels à volonté, indépendamment du groupe auquel ils appartiennent. Vous devez juste stocker le dernier menuitem vérifié. Le code Java ressemble à ceci:

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

Vous pouvez facilement ajouter des séparateurs en configurant l’arrière-plan des éléments de menu via XML à l'aide de 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"/>

Et utilisez LayerDrawable comme arrière-plan. Il préserve la superposition des ondulations de la conception des matériaux pour les 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>

Le résultat:

 enter image description here

9
Stanislav Perchenko

Faire des groupes différents comme la réponse de Nilesh crée un cloison entre les deux. Mais Pose le problème de deux éléments cochés dans le tiroir de navigation.

Un moyen simple comment j'ai géré cela était: 

    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);
}
8
Zorawar Sachdev

Je ne sais pas si cela est corrigé dans API 26 (Android 8) ou si c'était possible tout le temps. Je suis toujours un noob en programmation Android. Cependant, j'ai ajouté des groupes de parents comme ci-dessous. Test sur téléphone physique Android 6, 

  1. J'ai le diviseur 
  2. La sélection d'un élément parmi nav_g1 ou nav_g2 désélectionnera les autres éléments.
  3. Aucun remplissage supplémentaire n'a été ajouté en raison des groupes imbriqués.
  4. Je n'ai ajouté aucun code Java aux auditeurs

Code de menu

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

Remarques

  1. Comme mentionné dans ceci , chaque groupe doit avoir un identifiant unique pour montrer le diviseur.
  2. Selon this , les espaces de réponse correspondent aux spécifications de conception matérielle de Google.
  3. Il est nécessaire d'avoir Android:checkableBehavior="single" pour le groupe parent afin que le problème de la sélection de plusieurs éléments de menu dans this answer (mentionné dans les commentaires de hungryghost) ne se produise pas.

Et voici la capture d'écran

 Screenshot of the device screen

6
AaA

Je voulais des séparateurs au-dessus du premier article et après le dernier article. En utilisant la solution @Nilesh, je devais ajouter des éléments de menu factices et définir Activé à false, ce qui me semblait vraiment sale. Et si je veux faire d’autres choses intéressantes dans mon menu?

J'ai remarqué que NavigationView étend FrameLayout afin que vous puissiez y insérer votre propre contenu, comme vous le feriez pour un FrameLayout. J'ai ensuite défini un menu xml vide afin qu'il ne montre que ma mise en page personnalisée. Je comprends que cela va probablement à l’encontre du chemin que Google veut que nous prenions, mais si vous voulez un menu vraiment personnalisé, c’est un moyen facile de le faire.

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

Voici le style

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

Et tirable

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

Et le menu

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

modifier:

Au lieu de boutons, vous pouvez utiliser TextView avec drawable, qui imite les éléments de menu originaux:

 <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>
5
Justin Fiedler

Le mérite devrait aller à Zorawar pour la solution, désolé pour la duplication de la réponse, mais n'a pas pu ajouter autant de texte mis en forme dans un commentaire.

La solution de Zorawar fonctionne, le code pourrait être amélioré en tant que tel:

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);
}
1
Mushtaq Jameel

Si vous voulez ajouter un diviseur dynamiquement , vous pouvez simplement ajouter un sous-menu vide comme ceci:

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

cela va ajouter un diviseur.

assurez-vous simplement de passer dans le bon index lorsque vous utilisez menu.getItem(int index) 

0
Mohammad Mahtabi

La réponse de Nileh est juste, sauf qu'elle a un défaut de double vérification.

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

Donc en utilisant 

Android: checkableBehavior = "single"

avec identifiant unique résoudra le problème

0
Ajji

Si la réponse sélectionnée ne fonctionne pas pour vous, vous pouvez essayer d'ajouter ceci à onCreateOptionsMenu en plus de donner l'ID de groupe unique:

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

Outre les réponses précédentes, si vous souhaitez utiliser des séparateurs décoratifs mais ne souhaitez pas créer plusieurs groupes en raison de problèmes de "comportement vérifiable", vous pouvez affecter le même identifiant de groupe à tous vos groupes.

Exemple:

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

0
ievgen