21

I am using the new NavigationView from revision 22.2.0 of the support library by Google. It works perfectly fine to generate a navigation drawer populated using a menu res.

I was wondering is it possible to add a ListView or RecyclerView to the navigation drawer so that it can be populated using my custom adapter code, which allows for far greater flexibility than menu resources.

Here is my current XML:

<?xml version="1.0" encoding="utf-8"?>

<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:fitsSystemWindows="true"
    tools:context=".MainActivity">

    <FrameLayout
        android:id="@+id/content_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

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

    </FrameLayout>

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


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

Where in my XML would I add the ListView or RecyclerView?

EDIT

As per Basant's suggestion, I nested a ListView into the NavigationView. You lose the ability to inflate from a menu res (as far as I know) but it succeeds in what I want it to do. The header XML is unchanged, it is just included into XML.

New code:

<?xml version="1.0" encoding="utf-8"?>

<android.support.v4.widget.DrawerLayout
    android:id="@+id/drawer_layout"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:context=".MainActivity">

    <FrameLayout
        android:id="@+id/content_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

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

    </FrameLayout>

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

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

            <include
                android:id="@+id/navigation_drawer_header_include"
                layout="@layout/navigation_drawer_header" />

            <ListView
                android:id="@+id/navigation_drawer_list"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_below="@id/navigation_drawer_header_include"/>

        </RelativeLayout>

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


</android.support.v4.widget.DrawerLayout>
nabir
  • 1,447
  • 2
  • 12
  • 17

4 Answers4

22

You can just nest the ListView or RecyclerView inside the NavigationView.

<?xml version="1.0" encoding="utf-8"?>

<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:fitsSystemWindows="true"
    tools:context=".MainActivity">

    <FrameLayout
        android:id="@+id/content_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

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

    </FrameLayout>

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

        <ListView
            android:id="@+id/menuList"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>
</android.support.v4.widget.DrawerLayout>

NOTE: Keep in mind that if you use use a ListView inside it, you can't use the NavigationView's header. You will have to use the header view of the ListView that you are adding. Don't forget to remove the app:menu and app:header fields.

Basant Singh
  • 5,736
  • 2
  • 28
  • 49
  • Hello, I've tried that but the nav drawer breaks in the sense the navigation items are no longer clickable. Just saw your NOTE edit, I'll try that now. – nabir Jun 22 '15 at 11:14
  • 2
    I think you should not use the NavigationMenu in that case. Simply use a ListView or a more complex layout if you need, in place of a NavigationMenu. That will give you more flexibility. – Basant Singh Jun 22 '15 at 11:20
  • The reason I want to use NavigationView is due to built in scrim handling to give it that more material look, I have applied your suggestion and it seems to work. I will update my post to show the new code. – nabir Jun 22 '15 at 11:27
  • Check out the accepted answer here: http://stackoverflow.com/questions/26745300/navigation-drawer-semi-transparent-over-status-bar-not-working – Basant Singh Jun 22 '15 at 11:30
  • I was previously using that but the new NavigationView has that built in and I prefer using the new view since it is part of the library. – nabir Jun 22 '15 at 11:35
  • Thanks for the solution, it saved much of my time! – hetsgandhi Nov 26 '19 at 11:23
20

If you want to adding views inside the NavigationView you can do something like this. This way you have no restriction of adding Header on your NavigtionView with ListView.

 <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"
        android:fitsSystemWindows="false"

         >
        <LinearLayout
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
            <include layout="@layout/nav_header_main"
                android:id="@+id/my"
                />
            <ListView

                android:layout_weight="7"
                android:layout_width="match_parent"
                android:layout_height="0dp"
                android:id="@+id/list_view_inside_nav"></ListView>
        </LinearLayout>
    </android.support.design.widget.NavigationView>

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

That look something like this

example

Orest Hera
  • 6,706
  • 2
  • 21
  • 35
redblood
  • 542
  • 1
  • 4
  • 19
5

In response to Shubham's comment

This will not scroll the header view like the Navigation View does

I solved it by putting the LinearLayout inside a NestedScrollView. Now it scrolls properly with the header.

<android.support.v4.widget.NestedScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent">

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

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

        <android.support.v7.widget.RecyclerView
            android:id="@+id/nav_list"
            android:layout_width="match_parent"
            android:layout_height="@dimen/weight_based_height"
            android:layout_weight="1"
            android:nestedScrollingEnabled="false"/>
    </LinearLayout>

</android.support.v4.widget.NestedScrollView>
IsaiahJ
  • 454
  • 7
  • 19
1

Try this way

<android.support.design.widget.NavigationView
android:id="@+id/navigation"
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:orientation="vertical">

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

    <ListView
        android:id="@+id/lst_menu_items"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />
</LinearLayout>

Naveen T P
  • 6,955
  • 2
  • 22
  • 29
Mahendran Candy
  • 1,114
  • 17
  • 17