How to add footer to NavigationView - Android support design library?
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>
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>
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>
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>
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:
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>
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: