Comment ajouter un pied de page à NavigationView - Bibliothèque de conception de support Android?

122

Comment puis-je définir les paramètres de pied de page et les éléments de profil sur NavitationView? à ressemble au tiroir de navigation Boîte de réception par e-mail. Les NavitationViewéléments sont gonflés par la ressource de menu, mais je ne sais pas comment définir les éléments du bas sur une ressource de menu, ou comment puis-je définir une vue personnalisée NavigationViewou un décalage inférieur? J'ai essayé de mettre cela <LinearLayout...>en vue de pied de page, mais sur les petits écrans, le pied de page place les éléments et je ne peux pas faire défiler le menu, j'ai essayé de définir un remplissage de pied de page NavigationView, mais le pied de page prend également le rembourrage.

Ce n'est pas un défilement sur de petits écrans:

<android.support.design.widget.NavigationView
    android:id="@+id/drawer"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    app:headerLayout="@layout/kuona_drawer_header"
    app:menu="@menu/drawer">

    <LinearLayout...>

</android.support.design.widget.NavigationView>

PAS DE DÉFILEMENT

Cela défile, mais le pied de page est sur les éléments de menu:

<android.support.design.widget.NavigationView
    android:id="@+id/drawer"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    android:paddingBottom="96dp"
    app:headerLayout="@layout/kuona_drawer_header"
    app:menu="@menu/drawer">

    <LinearLayout...>

</android.support.design.widget.NavigationView>

entrez la description de l'image ici

res/menu/drawer.xmlFichier de menu du tiroir :

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <group android:checkableBehavior="single">
        <item
            android:id="@+id/action_current_list"
            android:checked="true"
            android:icon="@drawable/ic_current_list"
            android:title="@string/current_list" />
        <item
            android:id="@+id/action_manage_lists"
            android:icon="@drawable/ic_my_lists"
            android:title="@string/my_lists" />
        <item
            android:id="@+id/action_search_products"
            android:icon="@drawable/ic_search_black_24dp"
            android:title="@string/search_products" />
        <item
            android:id="@+id/action_deals"
            android:icon="@drawable/ic_product_promo"
            android:title="@string/deals" />
    </group>
</menu>
epool
la source
Dans quel emplacement avez-vous mis le fichier @ menu / tiroir ..
Psypher
Il est dans/res/menu/drawer.xml
epool
Y a-t-il une raison pour laquelle vous ne pouvez pas faire de «Commentaires» et de «Déconnexion» comme éléments de menu? Si la raison est que vous souhaitez modifier dynamiquement l'icône de menu pour "Déconnexion", vous devriez pouvoir le faire avec menuItem.setIcon(Drawable).
hungryghost
C'est juste pour les besoins, et personnellement, je veux savoir comment Google fait cela dans l'application Inbox par exemple.
epool
Cette question devient encore plus importante avec la mise à jour 23.1
Alex Sorokoletov

Réponses:

151

Si vous voulez un pied de page fixe (sans défilement) dans votre menu de navigation, vous devez envelopper NavigationView autour d'une autre disposition, comme vous l'avez publié. NavigationView fonctionne comme FrameLayout, donc cela finit par «empiler» la disposition interne au-dessus des éléments de menu NavigationView. Voici une façon de l'organiser, en utilisant LinearLayout pour les éléments de pied de page:

Pied de page fixe

<android.support.design.widget.NavigationView
    android:id="@+id/drawer"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    app:headerLayout="@layout/drawer_header"
    app:menu="@menu/drawer">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        android:clickable="true"
        android:orientation="vertical">
        <TextView
            android:id="@+id/footer_item_1"
            android:layout_width="match_parent"
            android:layout_height="48dp"
            android:gravity="center"
            android:text="Footer Item 1" />
        <TextView
            android:id="@+id/footer_item_2"
            android:layout_width="match_parent"
            android:layout_height="48dp"
            android:gravity="center"
            android:text="Footer Item 2" />
    </LinearLayout>

</android.support.design.widget.NavigationView>

J'ai utilisé TextViews dans cet exemple, mais vous pouvez utiliser ce que vous voulez pour les vues de pied de page. Pour éviter que les éléments du pied de page ne se chevauchent avec le bas du menu, ajoutez des éléments factices à la fin de votre fichier de ressources de menu (ils agiront comme des "entretoises"):

res / menu / tiroir.xml

<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <group>
        <item
            android:id="@+id/nav_item_1"
            android:icon="@drawable/ic_nav_item_1"
            android:title="Nav Item 1" />
        <item
            android:id="@+id/nav_item_2"
            android:icon="@drawable/ic_nav_item_2"
            android:title="Nav Item 2" />
        <item
            android:id="@+id/nav_item_3"
            android:icon="@drawable/ic_nav_item_3"
            android:title="Nav Item 3" />
        <item
            android:id="@+id/nav_item_4"
            android:icon="@drawable/ic_nav_item_4"
            android:title="Nav Item 4" />
        <item
            android:id="@+id/footer_spacer_1"
            android:checkable="false"
            android:enabled="false"
            android:orderInCategory="200"
            android:title="" />
        <item
            android:id="@+id/footer_spacer_2"
            android:checkable="false"
            android:enabled="false"
            android:orderInCategory="200"
            android:title="" />
    </group>
</menu>

Enfin, n'oubliez pas d'ajouter des écouteurs de clics dans votre activité pour les vues réelles du pied de page:

...
// Click listener for nav footer.
View navFooter1 = findViewById(R.id.footer_item_1);
navFooter1.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        // Do footer action
    }
});
View navFooter2 = findViewById(R.id.footer_item_2);
navFooter2.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        // Do footer action
    }
});
...

Pied de page défilant

Si vous autorisez le pied de page à défiler avec le reste de NavigationView, cela simplifie les choses (pas de dispositions supplémentaires ni d'écouteurs de clic). Ajoutez simplement les éléments de pied de page à votre fichier de ressources de menu en tant qu'unique <group>(cela créera une ligne de séparation ), et tout sera géré automatiquement et défilera ensemble:

res / menu / tiroir.xml

<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <group android:id="@+id/nav_menu">
        <item
            android:id="@+id/nav_item_1"
            android:icon="@drawable/ic_nav_item_1"
            android:title="Nav Item 1" />
        <item
            android:id="@+id/nav_item_2"
            android:icon="@drawable/ic_nav_item_2"
            android:title="Nav Item 2" />
        <item
            android:id="@+id/nav_item_3"
            android:icon="@drawable/ic_nav_item_3"
            android:title="Nav Item 3" />
        <item
            android:id="@+id/nav_item_4"
            android:icon="@drawable/ic_nav_item_4"
            android:title="Nav Item 4" />
    </group>
    <group android:id="@+id/nav_footer">
        <item
            android:id="@+id/nav_footer_1"
            android:icon="@drawable/ic_footer_item_1"
            android:title="Footer Item 1" />
        <item
            android:id="@+id/nav_footer_2"
            android:icon="@drawable/ic_footer_item_2"
            android:title="Footer Item 2" />
    </group>
</menu>
faim
la source
1
C'est juste pour les besoins, et personnellement, je veux savoir comment Google fait cela dans l'application Inbox par exemple.
epool
Je ne sais pas comment Google le fait dans l'application Gmail, mais d'après les apparences, cela ressemble à ce que j'ai décrit dans la réponse. Utilisez un autre <group> si vous voulez une ligne de séparation, sinon, le pied de page de navigation de l'application Gmail ressemble à des éléments de menu normaux (du moins pour moi).
hungryghost
1
Ahh, je comprends maintenant. Je pensais que vous parliez de l'application Gmail. Je n'ai pas installé l'application de boîte de réception, mais si vous recherchez un pied de page statique, vous avez raison, vous devez utiliser une mise en page distincte. Cela ne devrait pas être trop difficile cependant. Voyons voir ...
hungryghost
7
vous pouvez utiliser <dimen name="design_navigation_padding_bottom" tools:override="true">48dp</dimen> dans dimen.xmlau lieu d'utiliser des éléments factices dans le menu! c'est parfait !
Omid
1
Comment puis-je définir la police et la taille de police de l'élément de tiroir pour le texte du pied de page?
JEGADEESAN S
37

Je vais juste vous donner un indice pour le résoudre, mais je n'ai aucune chance de le tester sur NavigationView, et je suis presque sûr que cela fonctionnera

voici l'exemple de mise en page xml;

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:clipToPadding="false"
  android:paddingBottom="96dp">

  <TextView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#6F00" />

  <TextView
    android:layout_width="match_parent"
    android:layout_height="96dp"
    android:layout_gravity="bottom"
    android:layout_marginBottom="-96dp"
    android:background="#600F" />

</FrameLayout>

voici le résultat:

entrez la description de l'image ici

l'astuce consiste à appliquer un remplissage au parent et une marge moins à l'enfant.


Essai rapide:

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.NavigationView xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:layout_gravity="start"
  android:clipToPadding="false"
  android:paddingBottom="96dp"
  app:headerLayout="@layout/sample_header"
  app:menu="@menu/sample_menu">


  <TextView
    android:layout_width="match_parent"
    android:layout_height="96dp"
    android:layout_gravity="bottom"
    android:layout_marginBottom="-96dp"
    android:background="#600F"
    android:gravity="center"
    android:text="I STAND BY MY SELF" />

</android.support.design.widget.NavigationView>

entrez la description de l'image ici

Mohammad Ersan
la source
3
Cela peut fonctionner, mais les marges négatives sont plutôt piratées. Donc, personnellement, je les évite si possible.
hungryghost
Ce pied de page, si vous mettez des icônes centrées "en bas", vous pouvez changer en fonction de l'écran et sera coupé voir ce post stackoverflow.com/questions/32460312/...
livraison le
Pouvez-vous fournir un lien sur l'exemple complet?
livraison le
pouvons-nous le définir sur scrollable?
Ahmad Shahwaiz
27

Suite aux approches décrites dans les autres réponses de l'imbrication des vues de navigation, certains problèmes sont survenus:

  • Avec de nombreux éléments, ou en mode paysage, le pied de page chevauchait les éléments du menu
  • Si le vrai menu contient beaucoup d'éléments, la NavigationView imbriquée est défilable, ce qui ne semble pas agréable
  • Avoir deux NavigationViews dans l'imbrication, ne permettait pas de définir des vues personnalisées comme pied de page.
  • La gestion des vues de défilement imbriquées était un désordre (parfois deux barres de défilement apparaissaient, etc.)
  • Le pied de page fixe doit toujours être en bas (avec quelques éléments de menu ainsi qu'avec de nombreux éléments de menu)

Ma solution à tous ces problèmes était la suivante:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout ...>

    <include layout="@layout/main_content"/>

    <android.support.design.widget.NavigationView ...>

        <android.support.v4.widget.NestedScrollView
            ...
            android:fillViewport="true"
            android:scrollbars="vertical">

            <LinearLayout
                ...
                android:orientation="vertical">

                <android.support.design.widget.NavigationView
                    ...
                    app:elevation="0dp"
                    app:headerLayout="@layout/nav_header"
                    app:menu="@menu/nav_menu">
                </android.support.design.widget.NavigationView>

                <LinearLayout
                    android:id="@+id/spacer_to_bottom"
                    ...
                    android:layout_height="0dp"
                    android:layout_weight="1">
                </LinearLayout>

                <include layout="@layout/nav_footer"></include>
            </LinearLayout>
        </android.support.v4.widget.NestedScrollView>
    </android.support.design.widget.NavigationView>
</android.support.v4.widget.DrawerLayout>

Ici, NestedScrollView agit comme un parent défilant pour le sous-NavigationView. Cela signifie que le sous-NavigationView n'affiche jamais les barres de défilement lui-même, mais que tout le contenu est affiché de manière plate.

La mise en page «spacer_to_bottom» remplit tout l'espace restant, de sorte qu'avec quelques icônes de menu, le pied de page est toujours en bas.

Enfin, le pied de page fixe est ajouté à la mise en page linéaire, qui commence par le menu réel (sous-NavigationView), l'entretoise, et a en bas le pied de page.

Ici vous pouvez trouver l'exemple de travail complet comme AndroidStudio-Project: https://github.com/MarcDahlem/AndroidSidemenuFooterExample

En particulier, le tiroir de navigation peut être trouvé ici: https://github.com/MarcDahlem/AndroidSidemenuFooterExample/blob/master/app/src/main/res/layout/activity_main.xml

Captures d'écran:

Quelques articles De nombreux articles

Adreamus
la source
Qu'est-ce qui ne fonctionne pas exactement? Je peux fournir un exemple de projet si nécessaire, qui fonctionne très bien avec un pied de page défilant. @AndreaBaccega
Adreamus
Je suis d'accord avec @AndreaBaccega, ne fonctionne pas, affiche uniquement le menu de navigation et n'affiche pas le pied de page
RdlP
d'accord, deuxième avec des problèmes. Je vais créer un exemple de projet et le télécharger sur github. cu soon
Adreamus
J'ai ajouté un exemple de projet sur github: github.com/MarcDahlem/AndroidSidemenuFooterExample
Adreamus
Big upvote pour l'attribut d'élévation. J'allais avec la même approche, mais je ne pouvais pas me débarrasser de l'ombre du bas. Ensuite, j'ai trouvé ça. Je vous remercie!
Elvedin Selimoski
23

La réponse la plus simple consiste à ajouter un bouton dans la disposition du tiroir et à le définir par gravité en bas dans le navigationview.xml.

Voici le code:

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.NavigationView
   xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:app="http://schemas.android.com/apk/res-auto"
   android:id="@+id/navigation"
   android:layout_width="200dp"
   android:layout_height="match_parent"
   android:layout_gravity="start"
   app:headerLayout="@layout/navigation_header"
   app:menu="@menu/menu_navigation">

     <Button
            android:id="@+id/btn_sing_in"
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:text="@string/sign_in"
            android:layout_gravity="bottom"/>

</android.support.design.widget.NavigationView>

voici le résultat

Mohammed Fadhl
la source
2
Pour quelques éléments de menu, cela peut fonctionner. Mais dès que vous avez de nombreux éléments de menu, le bouton chevauchera avec les éléments de menu sur les petits appareils ou en mode paysage.
Adreamus
1
vrai cependant pour surmonter cela, vous pouvez mettre des éléments de menu vides.
Mohammed Fadhl
alligner le bas avec des éléments de menu vides pour différentes tailles d'écran est presque possible. Mais il existe un moyen général de le faire comme je l'ai décrit dans ma solution ;-) -> voir ma solution stackoverflow.com/a/37714353/1075072
Adreamus
17

Vous devez avoir une disposition de vue de navigation de conteneur, puis qui doit contenir deux autres dispositions de navigation. Vous les alignez en haut et en bas de la mise en page parent.

Je recommanderais d'utiliser une vue de navigation en tant que parent et non un FrameLayout car il s'agit essentiellement d'un ScrimFrameLayout et interagit mieux avec la barre d'état.

Voici un exemple de ce à quoi votre activité devrait ressembler:

<android.support.v4.widget.DrawerLayout 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"
android:id="@+id/layout_dashboard"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".MainActivity">

<!-- Activity content goes here -->

<android.support.design.widget.NavigationView
    android:id="@+id/navigation_drawer_container"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_gravity="start">

    <android.support.design.widget.NavigationView
        android:id="@+id/navigation_drawer"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="top"
        app:menu="@menu/menu_navigation_drawer" />

    <android.support.design.widget.NavigationView
        android:id="@+id/navigation_drawer_bottom"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        app:menu="@menu/menu_navigation_drawer_bottom" />

</android.support.design.widget.NavigationView>

Vous pouvez en lire plus et voir un exemple ici: http://blog.nitish.io/post/122633295558/android-design-library-navigationview-with-top

Nitish K.
la source
1
C'est vraiment une bonne solution. Mais le contenu enveloppant ne fonctionne pas à la fois sur NavigationView en haut et en bas. Vous devez donner une hauteur constante pour empêcher le bas du bloc NavigationView de bloquer NavigationView.
Olcay Ertaş
perfect solution
Bolein95
@Nitish comment éviter les chevauchements lorsque "@ + id / navigation_drawer" a plus de valeurs en mode portrait. il est passé derrière la vue de navigation inférieure. Dans mon cas, les éléments de menu de navigation supérieure sont peuplés de manière dynamique, la vue de navigation inférieure a des valeurs de menu statiques.
MohanRaj S
14

Je connais sa réponse tardive mais sa réponse parfaite et précise que la plupart des développeurs recherchent.

Pour ajouter un pied de page dans la vue de navigation, ajoutez une vue personnalisée dans le menu de navigation comme ci-dessous:

footer_navigation_menu.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">

    <android.support.v7.widget.AppCompatTextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:text="@string/version" />

    <android.support.v7.widget.AppCompatTextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:gravity="right" />

</RelativeLayout>

Maintenant, ajoutez la vue ci-dessus dans votre menu xml avec l'attribut group.Ainsi, il peut se différencier en pied de page dans le menu.

profile_menu.xml

<group android:checkableBehavior="single">

    <item
        android:id="@+id/nav_support"
        android:title="@string/nav_item_support" />

    <item
        android:id="@+id/nav_settings"
        android:title="@string/nav_item_settings" />

    <item
        android:id="@+id/nav_log_out"
        android:title="@string/nav_item_log_out" />
</group>
<group
    android:id="@+id/nav_footer">
    <item
        android:id="@+id/nav_log_version"
        app:actionLayout="@layout/footer_navigation_menu" />
</group>

C'est tout. Voici la sortie:

entrez la description de l'image ici

Sagar Maiyad
la source
Cela ne fonctionnera pas en cas de vue de dessous complexe car il donne une hauteur fixe à la vue de dessous.
Akash Bisariya le
Cela peut fonctionner, mais il n'y a aucun moyen de définir onClickListeners sur les vues à l'intérieur de la disposition du pied de page ... Dans mon cas, j'ai des boutons de médias sociaux sur le pied de page qui envoient à des URL externes, mais je n'ai pas pu obtenir les vues en utilisant leurs identifiants de quelque manière que ce soit Je pourrais penser à ...
Ramiro GM
12

C'est un peu décevant que NavigationView n'ait pas de disposition pour ajouter un pied de page. Mais tu peux essayer quelque chose comme ça,

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout 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"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:openDrawer="start">

    <include
        layout="@layout/app_bar_base"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <android.support.design.widget.NavigationView
        android:id="@+id/nav_view_container"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:fitsSystemWindows="false"
        android:layout_gravity="start"
        >

        <android.support.design.widget.NavigationView
            android:id="@+id/nav_view"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:scrollbarAlwaysDrawVerticalTrack="true"
            android:scrollbars="vertical"
            android:isScrollContainer="true"
            app:headerLayout="@layout/nav_header_base"
            app:menu="@menu/activity_base_drawer"
            android:layout_gravity="top"
            android:layout_marginBottom="x"
            />

        <android.support.design.widget.NavigationView
            android:id="@+id/nav_view_footer"
            android:layout_width="wrap_content"
            android:layout_height="x"
            app:headerLayout="@layout/hear_layout"
            app:menu="@menu/menu_items"
            android:scrollbars="none"
            android:layout_gravity="bottom"
            />

    </android.support.design.widget.NavigationView>

</android.support.v4.widget.DrawerLayout>

Dans le cas où votre pied de page est une liste,

    app:headerLayout="@null"
    app:menu="@menu/activity_base_drawer_footer"

Mais, s'il s'agit d'une sorte de vue personnalisée,

    app:headerLayout="@layout/my_cutom_footer_view"
    app:menu="@null"

De plus, dans ce cas, vous devrez définir x = height of your custom footer view

J'espère que ça aide.

Jay Nair
la source
Merci mec. tu as fait ma journée .. :)
SiddharthG
3
3 NavigationViews? Pourquoi? Pour les pires performances? S'il vous plaît, regardez certaines de ces vidéos: youtube.com/playlist?list=PLWz5rJ2EKKc9CBxr3BVjPTPoDPLdPIFCE
Louis CAD
@LouisCAD Si vous avez une solution qui fonctionne réellement, sans marge négative, partagez-la avec nous. J'ai le problème mentionné ici, et c'est la seule solution que je prends en considération. Ce n'est peut-être pas la solution parfaite et peut avoir un impact sur les performances ... mais sans autre implémentation, ne faites pas que des commentaires sur les questions de performances. Tout d'abord, les exigences des applications sont importantes. Si Google ne fournit pas de solution pour les exigences de votre application ... vous n'avez pas beaucoup d'options.
Dascalescu Vladut le
10

entrez la description de l'image iciJ'ai fait la même chose de la manière suivante:

 <?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout  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"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:openDrawer="start">

    <include
        layout="@layout/app_bar_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <android.support.design.widget.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        app:headerLayout="@layout/nav_header_main"
        app:menu="@menu/activity_main_drawer"
        >

        <LinearLayout android:layout_gravity="bottom"
            android:background="#20191d1e"
            android:layout_width="match_parent"
            android:paddingBottom="2dp"
            android:paddingLeft="@dimen/activity_horizontal_margin"
            android:paddingRight="@dimen/activity_horizontal_margin"
            android:paddingTop="2dp"
            android:orientation="horizontal"
            android:layout_height="wrap_content">

            <ImageView
                android:id="@+id/company_image_id"
                android:layout_width="50dp"
                android:layout_height="50dp"
                android:layout_margin="@dimen/margin1dp"
                android:padding="@dimen/margin2dp"
                android:src="@mipmap/ic_launcher_round"
                />

            <TextView
                android:id="@+id/txtCompanyName"
                android:layout_width="match_parent"                              android:layout_marginLeft="@dimen/margin3dp"
                android:layout_height="wrap_content"
                android:textSize="13dp" android:layout_gravity="center"
                android:textStyle="bold"
                android:textAppearance="@style/TextAppearance.AppCompat.Body1" />
        </LinearLayout>
    </android.support.design.widget.NavigationView>

</android.support.v4.widget.DrawerLayout>

Ici, l'essentiel est que je mette la gravité de la disposition en bas, par exemple

LinearLayout android:layout_gravity="bottom"
Manjeet Singh Goyal
la source
Avec cette solution, la vue de dessous flottera sur les éléments de menu (s'il y a plusieurs éléments de menu) ... Mais je veux qu'il soit fixé en bas.
Akash Bisariya le
7

Suite à votre approche, quelques changements mineurs peuvent vous aider à atteindre vos objectifs.

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom"
    android:background="@color/background_material_light">
    <TextView
       android:id="@+id/footer_item"
       android:layout_width="match_parent"
       android:layout_height="?attr/listPreferredItemHeight"
       android:background="?attr/selectableItemBackground"
       android:gravity="center_vertical"
       android:paddingLeft="?attr/listPreferredItemPaddingLeft"
       android:text="Something"
       android:textAppearance="?attr/textAppearanceListItem" />
</LinearLayout>

Et définissez certains éléments de stub dans le menu, de sorte que les éléments de menu ne se chevauchent pas.

<group>
    ...
    <item
        android:title=""
        android:orderInCategory="200"/>
</group>

Vous voudrez également ajouter un écouteur de clic à votre élément de pied de page.

tape-à-l'oeil
la source
Merci pour votre réponse, cela m'a donné une solution de contournement pour ajouter mon pied de page, mais j'espère accepter votre réponse si personne ne me donne une meilleure réponse pour faire mieux. +1
epool
Gardez vos options ouvertes en effet. Dans l'attente de meilleures réponses, les pieds de page sont importants.
razzledazzle
6

Ma solution avec pied de page fixe et menus déroulants (testée à 100%)

 <android.support.design.widget.NavigationView
    android:id="@+id/container_navigation"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_gravity=""
    android:nestedScrollingEnabled="true"
    android:scrollIndicators="none">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <android.support.design.widget.NavigationView
            android:id="@+id/navigation"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_above="@+id/navigation2"
            android:layout_gravity="top"
            android:nestedScrollingEnabled="true"
            android:paddingBottom="@dimen/dimen_20_dp"
            app:headerLayout="@layout/nav_header"
            app:itemIconTint="@color/black_800"
            app:itemTextColor="@color/black_800"
            app:menu="@menu/navigation_drawer_items">

        </android.support.design.widget.NavigationView>

        <android.support.design.widget.NavigationView
            android:id="@+id/navigation2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_gravity="bottom"
                android:background="@color/white_100"
                android:orientation="horizontal">

                <TextView
                    android:id="@+id/empty_spacer"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:drawableTop="@drawable/ic_search"
                    android:gravity="center"
                    android:text="Share" />

                <TextView
                    android:id="@+id/mnuRate"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:drawableTop="@drawable/ic_search"
                    android:gravity="center"
                    android:text="Rate" />

                <TextView
                    android:id="@+id/mnuHelp"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:drawableTop="@drawable/ic_search"
                    android:gravity="center"
                    android:text="Help" />
            </LinearLayout>
        </android.support.design.widget.NavigationView>

    </RelativeLayout>

</android.support.design.widget.NavigationView>
RD1819
la source
6

Voici comment j'arrive à ajouter une mise en page en bas de la navigation:

Bibliothèques mises à jour

    <com.google.android.material.navigation.NavigationView
    android:id="@+id/navigation_drawer_container"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_gravity="start">

    <androidx.core.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fillViewport="true">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">

                <com.google.android.material.navigation.NavigationView
                    android:id="@+id/nav_view"
                    android:layout_width="wrap_content"
                    android:layout_height="0dp"
                    android:layout_gravity="top"
                    android:layout_weight="0.8"
                    app:headerLayout="@layout/nav_header_home"
                    app:menu="@menu/activity_home_drawer" />

                <com.google.android.material.navigation.NavigationView
                    android:id="@+id/navigation_drawer_bottom"
                    android:layout_width="wrap_content"
                    android:layout_height="0dp"
                    android:layout_weight="0.2">

                    <LinearLayout
                        android:id="@+id/linearLayout"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:layout_alignParentBottom="true"
                        android:layout_below="@+id/scrollView"
                        android:orientation="vertical">

                        <TextView
                            android:id="@+id/text_dashboard_followUsAt"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:paddingLeft="16dp"
                            android:paddingStart="16dp"
                            android:text="Follow us at" />

                        <LinearLayout
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:orientation="horizontal"
                            android:paddingLeft="16dp"
                            android:paddingStart="16dp">

                            <ImageView
                                android:layout_width="wrap_content"
                                android:layout_height="wrap_content"
                                android:padding="5dp"
                                android:src="@drawable/fb" />

                            <ImageView
                                android:layout_width="wrap_content"
                                android:layout_height="wrap_content"
                                android:padding="5dp"
                                android:src="@drawable/fb" />

                            <ImageView
                                android:layout_width="wrap_content"
                                android:layout_height="wrap_content"
                                android:padding="5dp"
                                android:src="@drawable/fb" />
                        </LinearLayout>

                        <TextView
                            android:id="@+id/text_dashboard_version"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:layout_gravity="end"
                            android:layout_marginTop="25dp"
                            android:paddingBottom="5dp"
                            android:paddingEnd="16dp"
                            android:paddingRight="16dp"
                            android:text="Version 1.0" />
                    </LinearLayout>
                </com.google.android.material.navigation.NavigationView>
        </LinearLayout>
    </androidx.core.widget.NestedScrollView>
</com.google.android.material.navigation.NavigationView>
Zohaib Khaliq
la source
C'est la bonne solution pour ajouter une disposition de pied de page au bas de la vue de navigation. Bien qu'une mise en page linéaire ne soit pas nécessaire, j'ai édité dans cette réponse.
Akash Bisariya le
Comment avez-vous défini l'auditeur sélectionné pour l'élément de navigation dans cette activité? @zohaib khaliq
Akash Bisariya
5

NavigationViewle premier enfant ListViewcontient les éléments d'en-tête et de menu.

La seule chose nécessaire pour ajouter un pied de page est d'appeler .addFooterView à ListView

Plus d'infos: http://www.andreabaccega.com/blog/2015/08/28/how-to-add-footer-to-navigationview/

Copier le code coller:

public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);

    ListView listView = (ListView) navigationView.getChildAt(0);
    View toRet = LayoutInflater.from(view.getContext()).inflate(R.layout.drawer_footer, listView, false);

    // Manipulate the view (if you need to) before calling addFooterView.

    listView.addFooterView(toRet, null, false);
  }
Andrea Baccega
la source
10
sur le «com.android.support:design:23.1.0» ne fonctionne pas. il est devenu un RecyclerView dans le NavigationMenuPresenter
gordonpro
J'ai ajouté une nouvelle réponse qui pourrait résoudre votre problème.
Lukas
2

Mettez simplement une autre disposition dans votre NavigationView:

<android.support.design.widget.NavigationView 
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:background="#000000"
        app:itemTextColor="#FFFFFF"
        app:headerLayout="@layout/fragment_side_menu_header"
        app:menu="@menu/side_menu">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:layout_gravity="bottom">
        <TextView
            android:textColor="#FFFFFF"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="test" />
        <TextView
            android:textColor="#FFFFFF"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="test2" />
    </LinearLayout>
</android.support.design.widget.NavigationView>

L'astuce consiste à utiliser layout_gravity = "bottom" - cela mettra toute votre mise en page en bas et testera, test2 sont correctement empilés.

McOzD
la source
2

utilisez ceci..

<android.support.design.widget.NavigationView
    android:id="@+id/navigation"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    app:headerLayout="@layout/nav_header"
    app:itemIconTint="@color/accent"
    app:itemTextColor="@color/primary_text"
    app:menu="@menu/navigation_drawer_items">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        android:background="@color/grey_200"
        android:orientation="vertical">

        <View
            android:layout_width="match_parent"
            android:layout_height="@dimen/divider_height"
            android:background="@color/grey_600"/>

        <com.facebook.share.widget.LikeView
            android:id="@+id/like_view"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="start"
            android:padding="@dimen/small"/>

        <com.facebook.login.widget.LoginButton
            android:id="@+id/login_button"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="@dimen/small"/>
    </LinearLayout>
</android.support.design.widget.NavigationView>

puis définissez le remplissage inférieur sur NavigationMenuView

final View menuView = navigationView.getChildAt(0);
final View bottomView = navigationView.getChildAt(1);
bottomView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            menuView.setPadding(0, 0, 0, bottomView.getMeasuredHeight());
        }
    });
OM PRAKASH SEERVI
la source
2

Essayez ceci, ce travail pour moi.

<android.support.design.widget.NavigationView
                    android:id="@+id/nav_view1"
                    android:layout_width="wrap_content"
                    android:layout_height="match_parent"
                    android:layout_gravity="start"
                    android:fitsSystemWindows="true">

                    <ScrollView
                        android:layout_width="wrap_content"
                        android:layout_height="match_parent">

                    <LinearLayout
                        android:layout_width="wrap_content"
                        android:layout_height="match_parent"
                        android:orientation="vertical">

                        <android.support.design.widget.NavigationView
                            android:layout_width="wrap_content"
                            android:layout_height="match_parent"
                            android:id="@+id/nav_view"
                            app:headerLayout="@layout/nav_header_admin"
                            app:menu="@menu/activity_admin_drawer"/>

                        <LinearLayout
                            android:layout_width="match_parent"
                            android:layout_height="match_parent"
                            android:orientation="vertical"
                            android:id="@+id/lyNavFooter">

                           <!--INCLUDE YOUR FOOTER HERE -->

                        </LinearLayout>
                    </LinearLayout>

                    </ScrollView>



                </android.support.design.widget.NavigationView>
RdlP
la source
1

J'utilise ce formulaire, travaille pour moi. en paysage et portrait.

<android.support.design.widget.NavigationView
    android:id="@+id/nav_view"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_gravity="start">

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <android.support.design.widget.NavigationView
            android:id="@+id/navigation"
            android:layout_width="wrap_content"
            android:layout_height="0dp"
            android:layout_weight="1"
            app:headerLayout="@layout/master_main_header"
            app:itemIconTint="@color/blue"
            app:menu="@menu/menu_drawer">

        </android.support.design.widget.NavigationView>

        <Button
            android:id="@+id/master_btn_closession"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="0"
            android:background="@color/blue"
            android:text="Cerrar sesión" />
    </LinearLayout>
</android.support.design.widget.NavigationView>
Alex Zaraos
la source
1

<include
    layout="@layout/app_bar_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

<android.support.design.widget.NavigationView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    android:fitsSystemWindows="true"
    app:menu="@menu/activity_main_drawer">

    <android.support.v4.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fillViewport="true"
        android:scrollbars="vertical">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <android.support.design.widget.NavigationView
                android:id="@+id/nav_view"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                app:elevation="0dp"
                app:headerLayout="@layout/nav_header_main"
                app:menu="@menu/activity_main_drawer">
                ></android.support.design.widget.NavigationView>

            <LinearLayout
                android:id="@+id/spacer_to_bottom"
                android:layout_width="match_parent"
                android:layout_height="0dp"
                android:layout_weight="1"
                android:orientation="vertical" />

        </LinearLayout>
    </android.support.v4.widget.NestedScrollView>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        android:layout_marginBottom="0dp">

        <include layout="@layout/nav_footer_main" />

    </LinearLayout>
</android.support.design.widget.NavigationView>


la source
1
Ajoutez une explication avec une réponse sur la manière dont cette réponse aide OP à résoudre le problème actuel
ρяσѕρєя K
2
J'ai la solution. Vous devez inclure une disposition statique pour le pied de page, à l'intérieur du fichier <android.support.design.widget.NavigationView>...</android.support.design.widget.NavigationView>. pour plus de détails, veuillez consulter le repocitory github ( github.com/mehul0/AndroidSidemenuFooterExample-master )
1

Cela fonctionne pour moi pour mettre des images sur le pied de page du tiroir de navigation (orientation portrait et paysage)

    <?xml version="1.0" encoding="utf-8"?>
        <android.support.v4.widget.DrawerLayout 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"
            android:id="@+id/drawer_layout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:fitsSystemWindows="true"
            tools:openDrawer="start">

            <include
                layout="@layout/app_bar_main3"
                android:layout_width="match_parent"
                android:layout_height="match_parent" />

            <android.support.design.widget.NavigationView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_gravity="start"
                android:background="#f00"
                android:fitsSystemWindows="true"
                app:menu="@menu/activity_main3_drawer">

                <android.support.v4.widget.NestedScrollView
                    android:layout_width="match_parent"
                    android:fillViewport="true"
                    android:layout_height="match_parent"
                    android:scrollbars="vertical">

                    <LinearLayout
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:orientation="vertical">

                        <android.support.design.widget.NavigationView
                            android:id="@+id/nav_view"
                            app:elevation="0dp"
                            android:layout_height="wrap_content"
                            android:layout_width="match_parent"
                                android:background="#ff0"
                            app:headerLayout="@layout/nav_header_main3"
                            app:menu="@menu/activity_main3_drawer">
                            ></android.support.design.widget.NavigationView>

                        <LinearLayout
                            android:id="@+id/spacer_to_bottom"
                            android:layout_width="match_parent"
                            android:orientation="vertical"
                            android:background="#0f0"
                            android:layout_height="0dp"
                            android:layout_weight="1">
                            <include layout="@layout/nav_footer_main3"></include>
                        </LinearLayout>


                    </LinearLayout>
                </android.support.v4.widget.NestedScrollView>
            </android.support.design.widget.NavigationView>

        </android.support.v4.widget.DrawerLayout>

mon nav_footer_main3 est

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical" android:layout_width="match_parent"
        android:layout_height="60dp">
        <ImageView
            android:id="@+id/imageView"
            android:layout_gravity="center_horizontal"
            android:layout_width="200dp"
            android:layout_height="50dp"
            android:background="@drawable/logo_1" />
    </LinearLayout>
Sengson Haang Rai
la source
1

La structure de mise en page pour l'en-tête et le pied de page collants dans le menu du tiroir:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout>

    <android.support.design.widget.AppBarLayout>
        <android.support.v7.widget.Toolbar/>
    </android.support.design.widget.AppBarLayout>

    <LinearLayout>
        <include layout="@layout/drawer_header"/>
        <android.support.design.widget.NavigationView/>
        <include layout="@layout/drawer_footer"/>
    </LinearLayout>

</android.support.v4.widget.DrawerLayout>

La mise en page complète:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
    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"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:openDrawer="start">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/app_bar_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay"
        app:elevation="0dp">
        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?actionBarSize"
            app:layout_scrollFlags="scroll|enterAlways"
            app:popupTheme="@style/AppTheme.PopupOverlay" >
        </android.support.v7.widget.Toolbar>
    </android.support.design.widget.AppBarLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/white"
        android:layout_gravity="start"
        android:orientation="vertical">
        <include layout="@layout/drawer_menu_header"/>

        <android.support.design.widget.NavigationView
            android:id="@+id/drawer_menu_body"
            app:elevation="0dp"
            android:layout_height="0dp"
            android:layout_width="match_parent"
            android:layout_weight="1"
            android:background="@color/white"
            android:theme="@style/AppTheme.PopupOverlay"
            app:menu="@menu/main_drawer">
        </android.support.design.widget.NavigationView>

        <include layout="@layout/drawer_menu_footer"/>
    </LinearLayout>

</android.support.v4.widget.DrawerLayout>
locotracteur
la source
1

Essayez ceci, ce travail pour moi. https://github.com/MarcDahlem/AndroidSidemenuFooterExample/blob/master/app/src/main/res/layout/activity_main.xml

Cependant, vous désactivez NavigationViewScrolling pour un défilement plus fluide

private void disableNavigationViewScrolling(NavigationView navigationView) {
    if (navigationView != null) {
        NavigationMenuView navigationMenuView = (NavigationMenuView) navigationView.getChildAt(0);
        if (navigationMenuView != null) {
            navigationMenuView.setNestedScrollingEnabled(false);
        }
    }
}

Captures d'écran:

JB Pha Le
la source
0

Pied de page défilant pour la version> 23.xx

J'ai finalement réussi à réaliser ce que je voulais, malheureusement, il semble qu'il n'est plus possible de simplement saisir la référence à la ListView et d'ajouter un en-tête et un pied de page comme dans les versions inférieures à 23.xx (comme décrit par Andrea Baccega). Faire cela pour l'en-tête est toujours possible:

     <android.support.design.widget.NavigationView
     ..
     app:headerLayout="@layout/item_drawer_footer"
     ..
     />

Mais l'ajout d'un pied de page n'est pas possible pour le moment. Cependant, j'ai trouvé une solution de contournement au cas où vous essayez simplement d'ajouter un pied de page: vous inversez simplement la vue, cela ajoutera l'en-tête en bas qui se comporte comme un pied de page normal. Assurez-vous simplement de créer votre menu dans l'ordre inverse

    // Grab reference to the embedded recycler view
    RecyclerView mRecyclerView = (RecyclerView) navigationView.getChildAt(0);

    // Create a LinearLayoutManager and set it to reversed
    LinearLayoutManager mLayoutManager = new LinearLayoutManager(this);
    mLayoutManager.setReverseLayout(true);

    // Apply layout manager to the recycler view
    mRecyclerView.setLayoutManager(mLayoutManager);
Lukas
la source
0

Ma solution personnelle pour l'en-tête et le pied de page fixes étend NavigationView comme suit:

/**
 * Created by guness on 17.01.2018.
 */
class NavigationView : android.support.design.widget.NavigationView {

private var mHeader: View? = null
private var mFooter: View? = null
private var mMenuView: NavigationMenuView? = null

constructor(context: Context) : this(context, null)
constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
    val a = TintTypedArray.obtainStyledAttributes(context, attrs,
            R.styleable.NavigationView, defStyleAttr,
            R.style.Widget_Design_NavigationView)

    if (a.hasValue(R.styleable.NavigationView_footerLayout)) {
        inflateFooterView(a.getResourceId(R.styleable.NavigationView_footerLayout, 0))
    }

    a.recycle()

    (mFooter?.layoutParams as FrameLayout.LayoutParams?)?.gravity = Gravity.BOTTOM
}

init {
    (0 until childCount)
            .map { getChildAt(it) }
            .filter { it is NavigationMenuView }
            .forEach {
                mMenuView = it as NavigationMenuView
                mMenuView!!.overScrollMode = View.OVER_SCROLL_NEVER
            }
}

override fun inflateHeaderView(@LayoutRes res: Int): View {
    mHeader = LayoutInflater.from(context).inflate(res, this, false)
    setHeaderView(mHeader!!)
    return mHeader!!
}

@Deprecated("There can only be one header", ReplaceWith("#setHeaderView(view: View)"))
override fun addHeaderView(view: View) {
    throw IllegalAccessException("Please use #setHeaderView")
}

@UiThread
fun setHeaderView(view: View) {
    removeHeaderView()
    mHeader = view
    addView(mHeader, 0)
}

@Deprecated("No need to use params", ReplaceWith("#removeHeaderView()"))
override fun removeHeaderView(view: View) {
    removeHeaderView()
}

@UiThread
fun removeHeaderView() {
    if (mHeader != null) {
        removeView(mHeader)
        mHeader = null
    }
}

@Deprecated("No need to count, it is either 1 or zero", ReplaceWith("#hasHeader()"))
override fun getHeaderCount(): Int {
    return if (mHeader == null) 0 else 1
}

@Deprecated("No need to use params", ReplaceWith("#getHeaderView()"))
override fun getHeaderView(index: Int): View? {
    return getHeaderView()
}

fun getHeaderView(): View? {
    return mHeader
}

fun hasHeader(): Boolean {
    return mHeader != null
}

fun inflateFooterView(@LayoutRes res: Int): View {
    mFooter = LayoutInflater.from(context).inflate(res, this, false)
    setFooterView(mFooter!!)
    return mFooter!!
}

@UiThread
fun setFooterView(view: View) {
    removeFooterView()
    mFooter = view
    addView(mFooter, 0)
}

@UiThread
fun removeFooterView() {
    if (mFooter != null) {
        removeView(mFooter)
        mFooter = null
    }
}

fun hasFooter(): Boolean {
    return mFooter != null
}

fun getFooterView(): View? {
    return mFooter
}

fun setOnClickListener(@IdRes res: Int, listener: View.OnClickListener) {
    mHeader?.findViewById<View>(res)?.setOnClickListener(listener)
    mFooter?.findViewById<View>(res)?.setOnClickListener(listener)
}

override fun onMeasure(widthSpec: Int, heightSpec: Int) {
    super.onMeasure(widthSpec, heightSpec)
    val headerHeight = mHeader?.measuredHeight ?: 0
    val footerHeight = mFooter?.measuredHeight ?: 0
    val params = (mMenuView?.layoutParams as ViewGroup.MarginLayoutParams?)
    var changed = false
    if (params?.topMargin != headerHeight) {
        params?.topMargin = headerHeight
        changed = true
    }
    if (params?.bottomMargin != footerHeight) {
        params?.bottomMargin = footerHeight
        changed = true
    }
    if (changed) {
        mMenuView!!.measure(widthSpec, heightSpec)
    }
}
}

À l'origine, NavigationView crée un LinearLayout en tant que premier élément sur RecyclerView et fait défiler tout le contenu ensemble. L'idée à ce sujet est de créer des vues séparées pour le pied de page et l'en-tête, puis de les pousser vers le haut et le bas en utilisant Gravity. Plus tard, la mesure du contenu pour RecyclerView règle le contenu de défilement.

Voici la bibliothèque qui contient le code ci-dessus que j'ai écrit. https://github.com/guness/NavigationView

Bon côté de cela, je peux maintenant définir la vue du pied de page sur le xml tout comme l'en-tête sur le natif:

    app:footerLayout="@layout/nav_footer_main"
    app:headerLayout="@layout/nav_header_main"
guness
la source
0

Voici une solution qui ne nécessite pas d'imbrication et qui ajuste dynamiquement le remplissage inférieur du NavigationMenuView interne en fonction de la propre hauteur de la vue du pied de page, ce qui signifie que la hauteur du pied de page peut être définie sur wrap_contentet que vous pouvez modifier dynamiquement la visibilité du pied de page sur VISIBLEou GONE.

public class NavigationMenuFooterView extends LinearLayout {

    public NavigationMenuFooterView(Context context) {
        super(context);
    }

    public NavigationMenuFooterView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public NavigationMenuFooterView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onVisibilityChanged(@NonNull View changedView, int visibility) {
        update(getHeight());
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        update(h);
    }

    private void update(int height) {

        ViewParent parent = getParent();
        if (parent instanceof ViewGroup) {
            View navigationMenuView = ((ViewGroup) parent).findViewById(R.id.design_navigation_view);
            if (navigationMenuView != null) {
                if (getVisibility() == View.GONE) {
                    height = 0;
                }
                navigationMenuView.setPadding(navigationMenuView.getPaddingLeft(),
                        navigationMenuView.getPaddingTop(), navigationMenuView.getPaddingRight(), height);
            }
        }
    }
}

Vous devez définir l'id de design_navigation_view dans votre ids.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <item name="design_navigation_view" type="id"/>
    </resources>

Et utilisez comme ceci:

    <com.google.android.material.navigation.NavigationView
        android:id="@+id/navigation_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        app:headerLayout="@layout/drawer_header"
        app:itemBackground="@drawable/drawer_item"
        app:itemIconTint="@color/drawer_item"
        app:itemTextColor="@color/drawer_item"
        app:menu="@menu/menu_drawer">

        <util.NavigationMenuFooterView
            android:id="@+id/navigation_footer_view"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom"
            android:background="#fff"
            android:orientation="vertical">

            <View
                android:layout_width="match_parent"
                android:layout_height="1dp"
                android:background="#ddd" />

            <include layout="@layout/..." />

        </util.NavigationMenuFooterView>

    </com.google.android.material.navigation.NavigationView>

Testé avec com.google.android.material:material:1.0.0.

Oliver Jonas
la source
0

Si vous utilisez listview, vous pouvez essayer de cette façon. La vue de liste prend en charge la fonction d'affichage du pied de page, vous pouvez donc ajouter une vue de pied de page personnalisée R.layout.drawer_footer à l'aide de l'objet listview comme code ci-dessous

View footerView = LayoutInflater.from(getApplicationContext()).inflate(R.layout.drawer_footer, expandableListView, false);
TextView footer = footerView.findViewById(R.id.id_footer_wta_version_information);
expandableListView.addFooterView(footerView);

Dans mon cas, j'utilise expandableListView au lieu de listview (la listview a également la fonction addFooter). J'espère que cette façon vous aidera

phancuongviet
la source
-1

Mettez ces lignes dans la disposition de votre menu. J'espère que cela résoudra votre problème:

    <group
        android:id="@+id/grp11"
        android:checkableBehavior="single">

        <item


            android:title="" />
        <item


            android:title="" />
        <item

            android:title="" />
        <item


            android:title="" />
        <item


            android:title="" />
        <item

            android:title="" />

    </group>
rigide
la source