How to add footer to NavigationView - Android support design library?
AndroidAndroid Support-LibraryAndroid Design-LibraryAndroid 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>
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>
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:
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>
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:
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
That's it. Below is output:
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
I 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
<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>