How to add footer to NavigationView - Android support design library?

AndroidAndroid Support-LibraryAndroid Design-Library

Android Problem Overview


How can I set footer settings and profile items to NavitationView? to looks like the Inbox by email navigation drawer. The NavitationView items are inflated by menu resource, but I don't know how to set bottom items to a menu resource, or how can I set a custom view to NavigationView or an bottom offset? I have tried putting this <LinearLayout...> as footer view, but on small screens the footer puts over the items and I cant scroll the menu, I have tried to set a footer padding to NavigationView, but the footer takes the padding too.

This is not scrolling on small screens:

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

NOT SCROLLING

This scrolls, but the footer its over the menu items:

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

enter image description here

Drawer menu res/menu/drawer.xml file:

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

Android Solutions


Solution 1 - Android

If you want a fixed (non-scrolling) footer in your navigation menu, you need wrap NavigationView around another layout, like you've posted. NavigationView works like FrameLayout, so this ends up "stacking" the inner layout on top of the NavigationView menu items. Here's one way to arrange it, using LinearLayout for the footer items:

Fixed Footer

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

I used TextViews in this example, but you can use whatever you want for the footer views. To avoid the footer items overlapping with the bottom of the menu, add some dummy items to the end of your menu resource file (these will act like "spacers"):

res/menu/drawer.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>

Lastly, don't forget to add click listeners in your Activity for the actual footer views:

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

Scrolling Footer

If you allow the footer to scroll with the rest of the NavigationView though, it makes things simpler (no additional layouts or click listeners). Simply add the footer items to your menu resource file as a unique <group> (this will create a separator line), and everything will be handled automatically and scroll together:

res/menu/drawer.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>

Solution 2 - Android

I'll just give you the hint how to solve it, but I have no chance to test it on NavigationView, and am pretty sure it will work

here the sample layout 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>

here is the result:

enter image description here

the trick is by applying padding to parent and minus margin to the child.


Quick try:

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

enter image description here

Solution 3 - Android

Following the approaches described in the other answers of nesting navigation views, some problems came up:

  • With many items, or on landscape mode, the footer overlapped with the menu items
  • If the real menu has a lot of items, the nested NavigationView got scrollable, which was not looking nice
  • Having two NavigationViews in the nesting, did not allow to define custom views as footer.
  • Handling of nested scrollviews was a mess (sometimes two scrollbars showed up etc)
  • Fixed Footer should always be on the bottom (with few as well as with many menu items)

My solution for all of these problems was the following:

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

Here, the NestedScrollView acts as a scrolling parent for the sub-NavigationView. That means, the sub-NavigationView does never show up scrollbars itself, but the whole content is shown in a flat way.

The layout 'spacer_to_bottom' fills all remaining space, so that with few menu icons, the footer is still on the bottom.

Finally, the fixed footer is added to the linear layout,which starts with the real menu (sub-NavigationView), the spacer, and has on the bottom the footer.

Here you can find the complete working example as AndroidStudio-Project: https://github.com/MarcDahlem/AndroidSidemenuFooterExample

Especially the navigation drawer can be found here: https://github.com/MarcDahlem/AndroidSidemenuFooterExample/blob/master/app/src/main/res/layout/activity_main.xml

Screenshots:

Few items Many items

Solution 4 - Android

The simplest answer is to add a button inside the Drawer layout and set it gravity to bottom in the navigationview.xml.

Here is the 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>

Solution 5 - Android

I know its late answer but its perfect and accurate answer which most developers looking for.

For adding footer in navigation view, Add custom view into navigation menu just like below:

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>

Now, add above view into your menu xml with group attribute.So that, it can differentiate as footer in menu.

profile_menu.xml

http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" tools:showIn="navigation_view">

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

That's it. Below is output:

enter image description here

Solution 6 - Android

You need to have a container navigation view layout and then that should contain two more navigation layouts. You align those to top and bottom of the parent layout.

I would recommend using a navigation view as the parent and not a FrameLayout because it's essentially a ScrimFrameLayout and interacts with the status bar better.

Here's an example of what your activity should look like:

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

You can read more about it and see an example here: http://blog.nitish.io/post/122633295558/android-design-library-navigationview-with-top

Solution 7 - Android

Its kind of a bummer that NavigationView does not have a provision to add footer. But you can try something like this,

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

In case if your footer is a list,

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

But, if it is some kind of custom view,

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

Also, in this case, you will need to set x = height of your custom footer view

Hope it helps.

Solution 8 - Android

enter image description hereI made the same thing in the following manner:

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

Here the main thing is that i put the layout gravity to bottom e.g.

LinearLayout android:layout_gravity="bottom"

Solution 9 - Android

This is how I achieve to add layout at bottom of navigation:

Updated libraries

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

Solution 10 - Android

Following your approach, some minor changes can help what you want to achieve.

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

And set some stub items in the menu, so that menu items don't overlap.

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

Also you would want to add a click listener to your footer item.

Solution 11 - Android

My solution with fixed footer and scroll menus (100% tested)

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

Solution 12 - Android

NavigationView first child is the ListView containing both header and menu items.

The only thing needed to add a footer is call .addFooterView to the ListView

More info: http://www.andreabaccega.com/blog/2015/08/28/how-to-add-footer-to-navigationview/

Copy paste code:

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

Solution 13 - Android

Just put another layout inside your 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>

The trick is to use layout_gravity="bottom" - this will put your whole layout at the bottom and test,test2 are properly stacked.

Solution 14 - Android

use this..

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

then set bottom padding to 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());
        }
    });

   

Solution 15 - Android

Try this, this work for me.

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

Solution 16 - Android

I use this form, work for me. in landscape & 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>

Solution 17 - 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: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>

Solution 18 - Android

> This is working for me to put images on footer of navigation drawer(portrait and Landscape orientation)

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

> my nav_footer_main3 is

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

Solution 19 - Android

The layout structure for sticky header and footer in the drawer menu:

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

The complete layout:

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

Solution 20 - Android

Try this, this work for me.https://github.com/MarcDahlem/AndroidSidemenuFooterExample/blob/master/app/src/main/res/layout/activity_main.xml

However, you to disable NavigationViewScrolling for smoother scrolling

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

[Screenshots:][1] [1]: https://i.stack.imgur.com/hS50M.jpg

Solution 21 - Android

Here's a solution that doesn't require nesting and which dynamically adjusts the bottom padding of the internal NavigationMenuView based on the footer view's own height, which means the footer height can be set to wrap_content and you can dynamically change the footer's visibility to VISIBLE or 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);
            }
        }
    }
}

You need to define the id of design_navigation_view in your ids.xml:

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

And use like this:

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

Tested with com.google.android.material:material:1.0.0.

Solution 22 - Android

Scrolling footer for Version > 23.x.x

I finally managed to achieve what I wanted, unfortunately it looks like it is not longer possible to just grab the reference to the ListView and add a header and footer as in versions below 23.x.x (as described by Andrea Baccega). Doing this for the header is still possible:

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

But adding a footer is not possible at the moment. However, I found a workaround in case you are just trying to add a footer: You just reverse the view, this will add the header to the bottom which behaves like a normal footer. Just make sure to create your menu in reverse order

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

Solution 23 - Android

My personal solution for fixed header and footer is extending NavigationView as following:

/**
 * 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)
    }
}
}

Originally NavigationView creates an LinearLayout as first item on the RecyclerView and scrolls all the content together. The idea on this is to create separate Views for footer and header and then, push them to top and bottom using Gravity. Later on measuring content for RecyclerView settles the scrolling content.

Here is the library that contains above code I wrote. https://github.com/guness/NavigationView

Good side of this, now I can define footer view on the xml just like the header on native:

    app:footerLayout="@layout/nav_footer_main"
    app:headerLayout="@layout/nav_header_main"

Solution 24 - Android

If you are using listview, you can try this way. The list view support add footer view function, so you can add a custom footer R.layout.drawer_footer view using listview object as below code

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

In my case, I use expandableListView instead of listview (the listview also has addFooter function). Hope this way help you

Solution 25 - Android

Put these lines into your menu layout. I hope it will fix your issue:

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionepoolView Question on Stackoverflow
Solution 1 - AndroidhungryghostView Answer on Stackoverflow
Solution 2 - AndroidMohammad ErsanView Answer on Stackoverflow
Solution 3 - AndroidAdreamusView Answer on Stackoverflow
Solution 4 - AndroidMohammed FadhlView Answer on Stackoverflow
Solution 5 - AndroidSagar MaiyadView Answer on Stackoverflow
Solution 6 - AndroidNitish K.View Answer on Stackoverflow
Solution 7 - AndroidJay NairView Answer on Stackoverflow
Solution 8 - AndroidManjeet Singh GoyalView Answer on Stackoverflow
Solution 9 - Androidzohaib khaliqView Answer on Stackoverflow
Solution 10 - AndroidrazzledazzleView Answer on Stackoverflow
Solution 11 - AndroidRD1819View Answer on Stackoverflow
Solution 12 - AndroidAndrea BaccegaView Answer on Stackoverflow
Solution 13 - AndroidMcOzDView Answer on Stackoverflow
Solution 14 - AndroidOM PRAKASH SEERVIView Answer on Stackoverflow
Solution 15 - AndroidRdlPView Answer on Stackoverflow
Solution 16 - AndroidAlex ZaraosView Answer on Stackoverflow
Solution 17 - Androiduser5780466View Answer on Stackoverflow
Solution 18 - AndroidSengson Haang RaiView Answer on Stackoverflow
Solution 19 - Androids-hunterView Answer on Stackoverflow
Solution 20 - AndroidJB Pha LeView Answer on Stackoverflow
Solution 21 - AndroidOliver JonasView Answer on Stackoverflow
Solution 22 - AndroidLukasView Answer on Stackoverflow
Solution 23 - AndroidgunessView Answer on Stackoverflow
Solution 24 - AndroidphancuongvietView Answer on Stackoverflow
Solution 25 - AndroidstarkView Answer on Stackoverflow