How to add a collapsible menu item inside navigation drawer in android?
Asked Answered
F

4

17

I have a DrawerLayout enclosing a NavigationView and this layout activity serves as a common Navigation drawer for all the activities in my app. I am providing the menu resource for app:menu in navigation view. I have some menu items, but I want one menu item to be collapsible/expandable, so that when I click on it, it expands to show two submenus and collapses again on a second click.

I have added submenus by adding another <menu> inside the <item> but cant make it collapsible/expandable.

Additionally, I don't want to use ExpandableListView for my purpose. Instead, I just need to do some tweaks in menu resource file. Please just point me in the correct direction. I have searched Google only to find code, blogs, and examples for collapsible list items using ExpandableListView, but I need it to work with the NavigationView design widget from the design support Library.

Here's my code for the menu file:

<menu xmlns:android="http://schemas.android.com/apk/res/android">

<group android:checkableBehavior="single">
    <item
        android:id="@+id/nav_aboutus"
        android:title="About Us" />

    <item
        android:id="@+id/nav_faq"
        android:title="FAQs" />
    <item
        android:id="@+id/nav_share"
        android:title="Share" />
    <item
        android:id="@+id/nav_myaccount"
        android:title="My Account" />
    <item
        android:id="@+id/nav_legal"
        android:title="Legal" >
        <menu>
                <item
                    android:id="@+id/nav_tnc"
                    android:title="Terms and Conditions" />
                <item
                    android:id="@+id/nav_pp"
                    android:title="Privacy Policy" />
            </group>
        </menu>
    </item>

</menu>

I want Legal menu item to be expandable having two submenu items 'Terms and Conditions', 'Privacy Policy'.

Flotilla answered 12/3, 2016 at 11:0 Comment(2)
I don't think this is possible just using NavigationView.Meniscus
Yes !! It is not possible just using 'NavigationView' !! Thanks for helping though !!Flotilla
H
9

You can use expandable list views inside navigation drawers, I don't understand why you don't want to use them. More on that can be found here http://developer.android.com/reference/android/widget/ExpandableListView.html

If you insist on not using expandableListView, then the alternative is to design the expansion yourself using the menu's OnSelect for that specific item. Though I really don't know why you want this, you'd just be re-implementing the wheel.

Hush answered 12/3, 2016 at 11:7 Comment(3)
Thanks for the answer.. I shall not be using ExpandableListView.. I just managed to let it be the way it was... Simply menus and submenus without collapsing and expandable capabilities... Still +1 for the prompt answer !!Flotilla
Accepting this as the answer as I ended up using simple menus in my NavigationView !! :)Flotilla
@KanwarbirSingh sorry, but your own answer is too naive, you could update your own question and give an example how did you solve it at last.Woodprint
D
19

there is a trick to do this without using ExpandableListView.Add those menu items normally in menu layout file and hide/show them on item click of menu item under which you want to show them like this:

 public boolean onNavigationItemSelected(MenuItem item) {
        // Handle navigation view item clicks here.

        NavigationView nv= (NavigationView) findViewById(R.id.nav_view);
        Menu m=nv.getMenu();
        int id = item.getItemId();
        if (id == R.id.nav_posts) {
            boolean b=!m.findItem(R.id.nav_class).isVisible();
            //setting submenus visible state
            m.findItem(R.id.nav_class).setVisible(b);
            m.findItem(R.id.nav_dept).setVisible(b);
            m.findItem(R.id.nav_batch).setVisible(b);
            m.findItem(R.id.nav_campus).setVisible(b);
            return true;
        } else if (id == R.id.nav_walls) {
            boolean b=!m.findItem(R.id.nav_wall_events).isVisible();
            //setting submenus visible state
            m.findItem(R.id.nav_wall_events).setVisible(b);
            m.findItem(R.id.nav_wall_fun).setVisible(b);
            m.findItem(R.id.nav_wall_hadith).setVisible(b);
            m.findItem(R.id.nav_wall_news).setVisible(b);
            m.findItem(R.id.nav_wall_Poetry).setVisible(b);
            return true;
        } else if (id == R.id.nav_com) {

            m.findItem(R.id.nav_share).setVisible(false);
            m.findItem(R.id.nav_send).setVisible(false);

        } else if (id == R.id.nav_share) {

        } else if (id == R.id.nav_send) {

        }
        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        drawer.closeDrawer(GravityCompat.START);
        return true;
    }

where menu layout file is:

<?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/nav_posts"
            android:icon="@drawable/ic_menu_camera"
            android:title="Posts" />

        <item
            android:id="@+id/nav_class"
            android:title="Class"
            android:visible="false" />
        <item
            android:id="@+id/nav_dept"
            android:title="Department"
            android:visible="false" />
        <item
            android:id="@+id/nav_batch"
            android:title="Batch"
            android:visible="false" />
        <item
            android:id="@+id/nav_campus"
            android:title="Campus"
            android:visible="false" />


        <item
            android:id="@+id/nav_walls"
            android:icon="@drawable/ic_menu_gallery"
            android:title="Walls" />

        <item
            android:id="@+id/nav_wall_news"
            android:title="News"
            android:visible="false" />
        <item
            android:id="@+id/nav_wall_events"
            android:title="Events"
            android:visible="false" />
        <item
            android:id="@+id/nav_wall_fun"
            android:title="Fun"
            android:visible="false" />
        <item
            android:id="@+id/nav_wall_hadith"
            android:title="Hadith"
            android:visible="false" />
        <item
            android:id="@+id/nav_wall_Poetry"
            android:title="Poetry"
            android:visible="false" />


    </group>

    <item
        android:id="@+id/nav_com"
        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>
Disembark answered 6/4, 2017 at 16:40 Comment(2)
I found if I hide all the items in a submenu, the parent item gets hidden as well. Did you experience that?Wiredraw
I set the groupVisible to true when managing the events in OnNavigationItemSelectedListener, so that all items are shown. On the other part, @Disembark You blew it! I've tried the expandable list view responses and none of them work, straight to the point! thanksNickinickie
H
9

You can use expandable list views inside navigation drawers, I don't understand why you don't want to use them. More on that can be found here http://developer.android.com/reference/android/widget/ExpandableListView.html

If you insist on not using expandableListView, then the alternative is to design the expansion yourself using the menu's OnSelect for that specific item. Though I really don't know why you want this, you'd just be re-implementing the wheel.

Hush answered 12/3, 2016 at 11:7 Comment(3)
Thanks for the answer.. I shall not be using ExpandableListView.. I just managed to let it be the way it was... Simply menus and submenus without collapsing and expandable capabilities... Still +1 for the prompt answer !!Flotilla
Accepting this as the answer as I ended up using simple menus in my NavigationView !! :)Flotilla
@KanwarbirSingh sorry, but your own answer is too naive, you could update your own question and give an example how did you solve it at last.Woodprint
R
2

In menu layout file:

<item
        android:title="Setup"
        android:id="@+id/SetupGr"
        android:icon="@drawable/setup"
        />
<group
    android:checkableBehavior="none"
    android:id="@+id/SetupGroup">
    <item
        android:id="@+id/setupOutdoor"
        android:icon="@drawable/outdoor"
        android:title="Outdoor" />
    <item
        android:id="@+id/setupClocks"
        android:icon="@drawable/ic_launcher"
        android:title="Clocks" />
    <item
        android:id="@+id/selectMaps"
        android:icon="@drawable/map"
        android:title="Select map" />
</group>

In MyActivity.java - load desired menu:

public void LoadNavMenu(int iMenu){
    navigationView.getMenu().clear();
    navigationView.inflateMenu(iMenu);
    navigationView.getMenu().setGroupVisible(R.id.HelpGroup,false);
    navigationView.getMenu().setGroupVisible(R.id.SetupGroup,false);
}

And OnNavigationItemSelected:

public boolean onNavigationItemSelected(MenuItem item) {
    // Handle navigation view item clicks here.
    int id = item.getItemId();
    navigationView.getMenu().setGroupVisible(R.id.HelpGroup,false);
    navigationView.getMenu().setGroupVisible(R.id.SetupGroup,false);
    switch (item.getItemId()){
        case R.id.HelpGr:
            navigationView.getMenu().setGroupVisible(R.id.HelpGroup,true);
            navigationView.getMenu().setGroupVisible(R.id.SetupGroup,false);
            return true;
        case R.id.SetupGr:
            navigationView.getMenu().setGroupVisible(R.id.SetupGroup,true);
            navigationView.getMenu().setGroupVisible(R.id.HelpGroup,false);
            return true;
    }    
    base.closeDrawer(GravityCompat.START);
    return true;
}

I have 1 item - Setup - and when user select it - I set Group with id - SetupGroup - visible and return without closing drawer. Else - I set all groups invisible.

Revolving answered 6/9, 2017 at 16:45 Comment(0)
P
0

In addition to answers of @Stoyan Mihaylov and @arslan , do not implement visibility right in onNavigationItemSelected()! Menu will not refresh. Do it with delay, for example:

if (id == R.id.nav_settingsMenu) {
            //expandable submenu
            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    //Menu will refresh if toggled with delay
                    boolean b=!navigationView.getMenu().findItem(R.id.nav_1).isVisible();
                    navigationView.getMenu().findItem(R.id.nav_1).setVisible(b); //to keep state
                    navigationView.getMenu().setGroupVisible(R.id.nav_settingSubmenu,b);
                }
            },50);
            return true;
        }
Pydna answered 24/8, 2021 at 20:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.