Skip to content Skip to sidebar Skip to footer

Navigation Drawer: Add Titles To Groups, Not Items

I have a standard Navigation Drawer, pre-created by Android Studio and want to populate it with number of groups. I started with this:

Solution 1:

You are right, it's not possible to give groups a title. The only option seems to be to wrap groups into <item> and <menu> tags like this

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:title="General">
        <menu>
            <group android:checkableBehavior="single">
                <item
                    android:id="@+id/nav_camera"
                    android:icon="@drawable/ic_menu_camera"
                    android:title="Import" />
                <item
                    android:id="@+id/nav_gallery"
                    android:icon="@drawable/ic_menu_gallery"
                    android:title="Gallery" />
            </group>
        </menu>
    </item>

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

Resulting in a navigation drawer menu like this

Navigation Drawer


Solution 2:

You also required to have an outer group with android:checkableBehavior="single" so that no two item is selected one from First Category and other from Second Category. Here is the working code.

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:checkableBehavior="single">
<item
    android:title="First Category">
    <menu>
        <group
            android:id="@+id/menu_top"
            android:checkableBehavior="single">
            <item
                android:id="@+id/id1"
                android:icon="@drawable/drawable1"
                android:title="Title1" />

            <item
                android:id="@+id/id2"
                android:icon="@drawable/drawable2"
                android:title="Title2" />
        </group>
    </menu>
</item>
<item
    android:title="Second Category">
    <menu>
        <group
            android:id="@+id/menu_bottom"
            android:checkableBehavior="single">
            <item
                android:id="@+id/id3"
                android:icon="@drawable/drawable3"
                android:title="Title3" />

            <item
                android:id="@+id/id4"
                android:icon="@drawable/drawable4"
                android:title="Title4" />
        </group>
    </menu>
</item>
</group>
</menu>

Solution 3:

Here is well defined how to create menus.

http://developer.android.com/guide/topics/ui/menus.html

So in your case create your list in this order item->menu->group. that is to say:

 <item android:title="Title">
     <menu>
         <group android:checkableBehavior="single">
             <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" />
                .   .   .
                .   .   . 

Solution 4:

add xml class navigation_drawer_title:

<?xml version="1.0" encoding="utf-8"?>
<TextView
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="wrap_content"
        android:text="communicate"
        android:layout_height="wrap_content"/>

and change your navigationAdapter like this

private static final int TYPE_HEADER = 0; 
    private static final int TYPE_ITEM = 1;
    private static final int TYPE_SEPARATOR = 2;
    private static final int TYPE_TITLE = 3;
    @Override
        public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
        {
            View v = null;
            switch (viewType)
            {
                case TYPE_HEADER:
                    v = LayoutInflater.from(parent.getContext()).inflate(R.layout.navigation_drawer_header, parent, false); //Inflating the layout
                    break;
                case TYPE_ITEM:
                    v = LayoutInflater.from(parent.getContext()).inflate(R.layout.navigation_drawer_item, parent, false); //Inflating the layout
                    break;
                case TYPE_SEPARATOR:
                    v = LayoutInflater.from(parent.getContext()).inflate(R.layout.navigation_drawer_separator, parent, false); //Inflating the layout
                    break;

                case TYPE_TITLE:
                    v = LayoutInflater.from(parent.getContext()).inflate(R.layout.navigation_drawer_title, parent, false); //Inflating the layout
                    break;
            }
            return new ViewHolder(v, viewType); // Returning the created object

        }

and

@Override
    public int getItemViewType(int position)
    {
        if (position == 0)
            return TYPE_HEADER;
        if (navMenuItems.get(position - 1).getItemType() == NavItemType.Group)
            return TYPE_SEPARATOR;
        if (navMenuItems.get(position - 2).getItemType() == NavItemType.Group)
            return TYPE_TITLE

        return TYPE_ITEM;
    }

Solution 5:

For someone out there, that still struggling. Especially on DrawerLayout + Jetpack Navigation. I'm gonna drop my own implementation. After messing up with menu, NavigationView, and Jetpack Navigation. Just do a basic setup for Drawer Navigation and use this menu as NavigationView menus for 'named group'.

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    tools:showIn="navigation_view">

    <!-- Group for menu item without title -->
    <group android:checkableBehavior="single">
        <item
            android:id="@+id/yourFragment1"
            android:title="Fragment 1"/>
    </group>


    <item android:title="Group 1">
        <menu>
            <group
                android:checkableBehavior="single">
                <item
                    android:id="@+id/yourFragment2"
                    android:title="Fragment 2"/>

                <item
                    android:id="@+id/yourFragment3"
                    android:title="Fragment 3"/>
            </group>
        </menu>
    </item>

    <item android:title="Group 2">
        <menu>
            <group
                android:checkableBehavior="single">
                <item
                    android:id="@+id/yourFragment4"
                    android:title="Fragment 4"/>

                <item
                    android:id="@+id/yourFragment5"
                    android:title="Fragment 5"/>

                <item
                    android:id="@+id/yourFragment6"
                    android:title="Fragment 6"/>
            </group>
        </menu>
    </item>
</menu>

You can also add options other than navigating to another fragment, for example for the logout option. Just do like down below.

navigationView.setNavigationItemSelectedListener { dest ->

    if (dest.itemId == R.id.yourMenuIdOfLogoutInMenuXML) {
        logoutUser();
    } else {
        // This will navigate to a corresponding fragments
        NavigationUI.onNavDestinationSelected(dest, navController)

        // drawerLayout is reference to DrawerLayout widget component
        drawerLayout.closeDrawer(GravityCompat.START)
    }

    true
}

And if you want to check a certain menu programmatically you can just call

// navigationView is a reference to your NavigationView component.
navigationView.setCheckedItem(R.id.idOfMenuThatYouWantToCheck)

PS. For those of you that don't know how to set up DrawerLayout with Jetpack Navigation please refer to this example Setup Jetpack Navigation with DrawerLayout.


Post a Comment for "Navigation Drawer: Add Titles To Groups, Not Items"