3

I need to create a navigation drawer such that, the first menu contains 5 pre-defined items (these will never change). Below that first menu, I want to have a second menu that contains a variable amount of items with a custom layout.

Explained in an image:

enter image description here

Here is what my main activity looks like right now:

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

    <android.support.design.widget.CoordinatorLayout
        android:id="@+id/main_content"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <android.support.design.widget.AppBarLayout
            android:id="@+id/appbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:layout_scrollFlags="scroll|enterAlways"
                app:popupTheme="@style/AppTheme.PopupOverlay" />

            <android.support.design.widget.TabLayout
                android:id="@+id/tablayout"
                android:layout_width="match_parent"
                android:layout_height="48dp" />

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

        <android.support.v4.view.ViewPager
            android:id="@+id/container"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_behavior="@string/appbar_scrolling_view_behavior" />

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

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

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

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

            <ListView
                android:id="@+id/drawer_listview"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_gravity="left"
                android:choiceMode="singleChoice" />

        </LinearLayout>

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

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

Which works, except now I can't use the app:menu="@menu/navigation_drawer_items" property for NavigationView because the ListView items overlap the menu items.

Here is the menu XML:

<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:title="Communicate">
        <menu>
            <item
                android:id="@+id/nav_share"
                android:icon="@drawable/ic_menu_share"
                android:title="Share" />
            <item
                android:id="@+id/nav_send"
                android:icon="@drawable/ic_menu_send"
                android:title="Send" />
        </menu>
    </item>
</menu>

Is there a way that I can load the menu XML AND show a custom layout below the menu? Is there a different want to do this?

Amit Upadhyay
  • 7,179
  • 4
  • 43
  • 57
user7524835
  • 31
  • 1
  • 4

4 Answers4

0

NavigationView does not seem to have support for custom footers. In my project I have made this little monster based on some other SO answers.

<android.support.v4.widget.DrawerLayout
     android:id="@+id/drawer_layout"
     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:background="@color/colorPrimary"
     android:fitsSystemWindows="true"
     tools:context=".ui.MainActivity">

    ...screen content...

    <android.support.design.widget.NavigationView
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:fitsSystemWindows="true">

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

            <RelativeLayout
                android:layout_width="wrap_content"
                android:layout_height="0dp"
                android:layout_weight="1">

                <android.support.design.widget.NavigationView
                    android:id="@+id/navigation_view"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="top"
                    app:elevation="0dp"
                    app:headerLayout="@layout/drawer_header"
                    app:menu="@menu/drawer">
                </android.support.design.widget.NavigationView>
                <View
                    android:layout_width="match_parent"
                    android:layout_height="21dp"
                    android:layout_alignParentBottom="true"
                    android:background="@drawable/bg_navbarscroll"/>

            </RelativeLayout>

            <include
                android:id="@+id/premium_footer"
                layout="@layout/drawer_footer"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"/>
        </LinearLayout>
    </android.support.design.widget.NavigationView>
</android.support.v4.widget.DrawerLayout>

What we have here are two nested NavigationViews. This may be a bit overkill but I wasn't able to make it work otherwise. This is based on the work in this question so all the credit goes there: How to add footer to NavigationView - Android support design library?

The real NavView is the inner one, it has the header, it has the menu, but it doesn't fit system windows. The first one fits system windows and handles the drawer movement. The problem you are facing is because the ListView does not know the size the content in NavView holds. So you need to make sure nothing is in the same layout so there is no overlapping. Your listView has to be in parent of the NavView parent. And because this will likely destroy the mechanism for controls of the DrawerLayout you need the first, outer NavigationView.

Alternatively if you can live without inflating menus in drawer just make a custom "old-fashioned" drawer like the ones before the NavigationViews appeared.

Community
  • 1
  • 1
mhenryk
  • 551
  • 5
  • 13
0

In my case I wanted to add some info text at the bottom of the drawer. After fiddling a bit I managed to obtain the desired result by adding a ConstraintLayout in the NavigationView:

    <androidx.drawerlayout.widget.DrawerLayout
        android:id="@+id/drawer_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true">

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


        <com.google.android.material.navigation.NavigationView
            android:id="@+id/nav_view"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_gravity="start"
            android:fitsSystemWindows="true"
            app:headerLayout="@layout/nav_header_main"
            app:menu="@menu/activity_main_drawer">

            <androidx.constraintlayout.widget.ConstraintLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent">

                <TextView
                    android:id="@+id/bottom_content"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    app:layout_constraintBottom_toBottomOf="parent"
                    app:layout_constraintEnd_toEndOf="parent"
                    app:layout_constraintStart_toStartOf="parent" />

            </androidx.constraintlayout.widget.ConstraintLayout>
        </com.google.android.material.navigation.NavigationView>

For now everything seems to be working, but there could be some hidden pitfalls.

Dude
  • 1,202
  • 21
  • 30
0

A fixed (non-scrolling) footer in your navigation menu, can be achieved by wraping the NavigationView around another layout, like you've posted. you can arrange it, using LinearLayout for the footer items as shown below:

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

You can use whatever you want in place of the TextViews. Structuring your bottom layout well is necessary to avoid overlapping of views.

Menu XML

<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:title="Communicate">
    <menu>
        <item
            android:id="@+id/nav_share"
            android:icon="@drawable/ic_menu_share"
            android:title="Share" />
        <item
            android:id="@+id/nav_send"
            android:icon="@drawable/ic_menu_send"
            android:title="Send" />
    </menu>
</item>

You can finally add onclick listeners to your layout

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
    }
});
Paul Kumchi
  • 211
  • 4
  • 7
0

This will help you must set your custom adapter in recyclerView.

<androidx.drawerlayout.widget.DrawerLayout
    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:context=".DrawerActivity">

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


        <androidx.appcompat.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="@color/purple_200" />

    </LinearLayout>


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


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


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


            <androidx.recyclerview.widget.RecyclerView

                android:id="@+id/recyclerView"
                android:layout_width="match_parent"
                android:layout_height="match_parent" />

        </LinearLayout>

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

</androidx.drawerlayout.widget.DrawerLayout>
General Grievance
  • 4,555
  • 31
  • 31
  • 45