Adding expandableListView to NavigationView
Asked Answered
F

5

35

I have a menu defined in xml:

<group android:checkableBehavior="single" android:id="@+id/group">
    <item
        android:id="@+id/grades"
        android:icon="@drawable/ic_font_download_black_48dp"
        android:checked="false"
        android:title="Grades" >
        <menu>
            <item
                android:id="@+id/mp1"
                android:icon="@drawable/ic_looks_one_black_24dp"
                android:checked="false"
                android:title="MP1" />
            <item
                android:id="@+id/mp2"
                android:icon="@drawable/ic_looks_two_black_24dp"
                android:checked="false"
                android:title="MP2" />
            <item
                android:id="@+id/mp3"
                android:icon="@drawable/ic_font_download_black_48dp"
                android:checked="false"
                android:title="MP3" />
            <item
                android:id="@+id/mp4"
                android:icon="@drawable/ic_font_download_black_48dp"
                android:checked="false"
                android:title="MP4" />
        </menu>
    </item>
    <item
        android:id="@+id/schedule"
        android:icon="@drawable/ic_event_black_48dp"
        android:checked="false"
        android:title="Schedule" />
    <item
        android:id="@+id/attendance"
        android:icon="@drawable/ic_assignment_ind_black_48dp"
        android:checked="false"
        android:title="Attendance" />
    <item
        android:id="@+id/assignments"
        android:icon="@drawable/ic_assignment_black_48dp"
        android:checked="false"
        android:title="Assignments" />
    <item
        android:id="@+id/studentInfo"
        android:icon="@drawable/ic_account_circle_black_48dp"
        android:checked="false"
        android:title="Student Details" />
</group>
<group android:id="@+id/group2" android:checkableBehavior="single">
    <item
        android:id="@+id/placeholder"
        android:icon="@drawable/ic_android_black_48dp"
        android:checked="false"
        android:title="Placeholder" />
    <item
        android:id="@+id/placeholder2"
        android:icon="@drawable/ic_android_black_48dp"
        android:checked="false"
        android:title="Placeholder" />
</group>

which adds a submenu which looks like this: enter image description here

However, I am unable to make this submenu look like this: (collapsable)

enter image description here

I now know that I need to implement an expandableListView, but I am not sure how this would fit in with the menu I have already created.

Any advice is appreciated

Fivepenny answered 6/9, 2015 at 2:25 Comment(3)
Check this dropbox.com/s/qtd51lxypodvojf/NavigationDrawer.zip for demo testingQuotable
The submenus won't collapse in NavigationView. I wrote some code to try to put an ExpandableListVIew in the NavigationView's headerLayout (with no menu). The list view ends up being wrapped so that you can only see a single item. So here's the deal: NavigationView is only meant to do very simple menus. If you want to have expandable menu items, additional icons, or anything else fancy, you will have to forget about NavigationView and go back to having a simple Fragment for the nav drawer doing all your own layout. Or you can search GitHub for a nav drawer project.Condign
@Kris larson the example I provided uses a navigationViewFivepenny
S
85

You can create it using custom ListView.

See the code below activity_navigation_view.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"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!" />

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

        <ExpandableListView
            android:id="@+id/navigationmenu"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_marginTop="192dp"
            android:background="@android:color/white">
        </ExpandableListView>
    </android.support.design.widget.NavigationView>
</android.support.v4.widget.DrawerLayout>

The adapter for expandable list view is as follows.

ExpandableListAdapter.java

import android.content.Context;
import android.graphics.Typeface;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.ExpandableListView;
import android.widget.ImageView;
import android.widget.TextView;

import java.util.HashMap;
import java.util.List;

public class ExpandableListAdapter extends BaseExpandableListAdapter {
    private Context mContext;
    private List<ExpandedMenuModel> mListDataHeader; // header titles

    // child data in format of header title, child title
    private HashMap<ExpandedMenuModel, List<String>> mListDataChild;
    ExpandableListView expandList;

    public ExpandableListAdapter(Context context, List<ExpandedMenuModel> listDataHeader, HashMap<ExpandedMenuModel, List<String>> listChildData, ExpandableListView mView) {
        this.mContext = context;
        this.mListDataHeader = listDataHeader;
        this.mListDataChild = listChildData;
        this.expandList = mView;
    }

    @Override
    public int getGroupCount() {
        int i = mListDataHeader.size();
        Log.d("GROUPCOUNT", String.valueOf(i));
        return this.mListDataHeader.size();
    }

    @Override
    public int getChildrenCount(int groupPosition) {
        int childCount = 0;
        if (groupPosition != 2) {
            childCount = this.mListDataChild.get(this.mListDataHeader.get(groupPosition))
                .size();
        }
        return childCount;
    }

    @Override
    public Object getGroup(int groupPosition) {
        return this.mListDataHeader.get(groupPosition);
    }

    @Override
    public Object getChild(int groupPosition, int childPosition) {
        Log.d("CHILD", mListDataChild.get(this.mListDataHeader.get(groupPosition))
            .get(childPosition).toString());
        return this.mListDataChild.get(this.mListDataHeader.get(groupPosition))
            .get(childPosition);
    }

    @Override
    public long getGroupId(int groupPosition) {
        return groupPosition;
    }

    @Override
    public long getChildId(int groupPosition, int childPosition) {
        return childPosition;
    }

    @Override
    public boolean hasStableIds() {
        return false;
    }

    @Override
    public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
        ExpandedMenuModel headerTitle = (ExpandedMenuModel) getGroup(groupPosition);
        if (convertView == null) {
            LayoutInflater infalInflater = (LayoutInflater) this.mContext
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = infalInflater.inflate(R.layout.listheader, null);
        }
        TextView lblListHeader = (TextView) convertView
            .findViewById(R.id.submenu);
        ImageView headerIcon = (ImageView) convertView.findViewById(R.id.iconimage);
        lblListHeader.setTypeface(null, Typeface.BOLD);
        lblListHeader.setText(headerTitle.getIconName());
        headerIcon.setImageResource(headerTitle.getIconImg());
        return convertView;
    }

    @Override
    public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
        final String childText = (String) getChild(groupPosition, childPosition);

        if (convertView == null) {
            LayoutInflater infalInflater = (LayoutInflater) this.mContext
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = infalInflater.inflate(R.layout.list_submenu, null);
        }

        TextView txtListChild = (TextView) convertView
            .findViewById(R.id.submenu);

        txtListChild.setText(childText);

        return convertView;
    }

    @Override
    public boolean isChildSelectable(int groupPosition, int childPosition) {
        return true;
    }
}

list_submenu.xml is as follows.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical">

    <TextView
        android:id="@+id/submenu"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="20dp"
        android:padding="10dp"
        android:textColor="#000000"
        android:textSize="18sp"/>
</LinearLayout>

listheader.xml is as follows.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="2dp"
              android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginLeft="20dp"
        android:orientation="horizontal">

        <ImageView
            android:id="@+id/iconimage"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:paddingBottom="10dp"
            android:paddingLeft="10dp"
            android:paddingTop="10dp"/>

        <TextView
            android:id="@+id/submenu"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="10dp"
            android:textColor="#000000"
            android:textSize="20sp"/>

    </LinearLayout>

</LinearLayout>

In your navigation view activity, set the adapter for the expandable list view. NavigationViewActivity.java

public class NavigationViewActivity extends AppCompatActivity {

    private DrawerLayout mDrawerLayout;
    ExpandableListAdapter mMenuAdapter;
    ExpandableListView expandableList;
    List<ExpandedMenuModel> listDataHeader;
    HashMap<ExpandedMenuModel, List<String>> listDataChild;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_navigation_view);
        final ActionBar ab = getSupportActionBar();
        /* to set the menu icon image*/
        ab.setHomeAsUpIndicator(android.R.drawable.ic_menu_add);
        ab.setDisplayHomeAsUpEnabled(true);
        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        expandableList = (ExpandableListView) findViewById(R.id.navigationmenu);
        NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);

        if (navigationView != null) {
            setupDrawerContent(navigationView);
        }

        prepareListData();
        mMenuAdapter = new ExpandableListAdapter(this, listDataHeader, listDataChild, expandableList);

        // setting list adapter
        expandableList.setAdapter(mMenuAdapter);

        expandableList.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
            @Override
            public boolean onChildClick(ExpandableListView expandableListView, View view, int i, int i1, long l) {
                //Log.d("DEBUG", "submenu item clicked");
                return false;
            }
        });
        expandableList.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {
            @Override
            public boolean onGroupClick(ExpandableListView expandableListView, View view, int i, long l) {
                //Log.d("DEBUG", "heading clicked");
                return false;
            }
        });
    }

    private void prepareListData() {
        listDataHeader = new ArrayList<ExpandedMenuModel>();
        listDataChild = new HashMap<ExpandedMenuModel, List<String>>();

        ExpandedMenuModel item1 = new ExpandedMenuModel();
        item1.setIconName("heading1");
        item1.setIconImg(android.R.drawable.ic_delete);
        // Adding data header
        listDataHeader.add(item1);

        ExpandedMenuModel item2 = new ExpandedMenuModel();
        item2.setIconName("heading2");
        item2.setIconImg(android.R.drawable.ic_delete);
        listDataHeader.add(item2);

        ExpandedMenuModel item3 = new ExpandedMenuModel();
        item3.setIconName("heading3");
        item3.setIconImg(android.R.drawable.ic_delete);
        listDataHeader.add(item3);

        // Adding child data
        List<String> heading1 = new ArrayList<String>();
        heading1.add("Submenu of item 1");

        List<String> heading2 = new ArrayList<String>();
        heading2.add("Submenu of item 2");
        heading2.add("Submenu of item 2");
        heading2.add("Submenu of item 2");

        listDataChild.put(listDataHeader.get(0), heading1);// Header, Child data
        listDataChild.put(listDataHeader.get(1), heading2);

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case android.R.id.home:
                mDrawerLayout.openDrawer(GravityCompat.START);
                return true;
        }
        return super.onOptionsItemSelected(item);
    }

    private void setupDrawerContent(NavigationView navigationView) {
        //revision: this don't works, use setOnChildClickListener() and setOnGroupClickListener() above instead
        navigationView.setNavigationItemSelectedListener(
            new NavigationView.OnNavigationItemSelectedListener() {
                @Override
                public boolean onNavigationItemSelected(MenuItem menuItem) {
                    menuItem.setChecked(true);
                    mDrawerLayout.closeDrawers();
                    return true;
                }
            });
    }

}

ExpandedMenuModel class contains menu item details as follow.

ExpandedMenuModel.java

public class ExpandedMenuModel {

    String iconName = "";
    int iconImg = -1; // menu icon resource id

    public String getIconName() {
        return iconName;
    }
    public void setIconName(String iconName) {
        this.iconName = iconName;
    }
    public int getIconImg() {
        return iconImg;
    }
    public void setIconImg(int iconImg) {
        this.iconImg = iconImg;
    } 
}

[Side note]:

  1. Don't put import android.widget.ExpandableListAdapter; in NavigationViewActivity.java. This mistake can happen if you resolve import by Alt+Enter before create the file ExpandableListAdapter.java.

  2. Put compile 'com.android.support:design:23.3.0' in app's build.gradle, it's for "NavigationView" and its "import android.support.design.widget.NavigationView;" After that (Might require rebuild first) you can do Alt-Enter to resolve import.

The file hierarchy should look like (3 .java and 3 .xml from above):

enter image description here

The output screenshot:

enter image description here

Spurious answered 19/9, 2015 at 5:3 Comment(11)
What is ExpandedMenuModel?? @PriyankJamille
@MicheleLacorte ExpandedMenuModel class contains details of menu item, see my edited answer.Spurious
the layout is not just as one of the photo , more when you click on a section of the color " gray " as the button does not embrace the whole line but in part. @PriyankJamille
@MicheleLacorte This is just for reference, You can change the layout according to your requirement & design. :)Spurious
thank you , but I can not get it to work the same as the photo layout , you may update the code ? @PriyankJamille
Can this be combined with regular (non-expandable) menu items?Crummy
@PriyankPatel can i add n level of expandable in navigatinview in this way...?Sunless
more than two header items are adding child... how to add more header and child also?Sciuroid
ExpandedMenuModel is having problem... crashing the apps... so wiped out with simple String typeSciuroid
Hello, I'm finding this answer useful for my app, however I came across and issue while trying to mix both an expandable list and regular menu items in a navigation drawer. It seems this answer focuses on building the navigation based on expandable lists, as it shows on the posted app screenshot, but is there a way to mix them both, as in Steve's example screenshot? He's screenshot features regular items plus the expandable lists. Thank you!Onofredo
By the way, I tried adding empty items to see if it could work that way even if they looked like lists, but the app crashes whenever the last item is selected if it's empty, or if an empty item preceded by another empty item is selected even if it isn't the last one, this is due to a NullPointerException in the getChild method from ExpandableListAdapter.javaOnofredo
S
1

MainActivity.java

import android.graphics.Color;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.NavigationView;
import android.support.design.widget.Snackbar;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ExpandableListView;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

public class MainActivity extends AppCompatActivity
        implements NavigationView.OnNavigationItemSelectedListener {

    View view_Group;
    private DrawerLayout mDrawerLayout;
    ExpandableListAdapter mMenuAdapter;
    ExpandableListView expandableList;
    List<String> listDataHeader;
    HashMap<String, List<String>> listDataChild;
    //Icons, use as you want
    static int[] icon = { R.drawable.ico1, R.drawable.ico1,
            R.drawable.ico1, R.drawable.ico1,
            R.drawable.ico1, R.drawable.ico1, R.drawable.ico1};
    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        if(android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.JELLY_BEAN_MR2) {
            expandableList.setIndicatorBounds(expandableList.getRight()- 80, expandableList.getWidth());
        } else {
            expandableList.setIndicatorBoundsRelative(expandableList.getRight()- 80, expandableList.getWidth());
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        supportRequestWindowFeature(Window.FEATURE_ACTION_BAR_OVERLAY);
        //requestWindowFeature(Window.FEATURE_NO_TITLE);
        this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

        setContentView(R.layout.activity_main);

        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });

        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
                this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
        drawer.setDrawerListener(toggle);
        toggle.syncState();

        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        expandableList = (ExpandableListView) findViewById(R.id.navigationmenu);

        NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
        navigationView.setNavigationItemSelectedListener(this);
        navigationView.setItemIconTintList(null);

        if (navigationView != null) {
            setupDrawerContent(navigationView);
        }
        prepareListData();
        mMenuAdapter = new ExpandableListAdapter(this, listDataHeader, listDataChild);

        // setting list adapter
        expandableList.setAdapter(mMenuAdapter);

        expandableList.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
            @Override
            public boolean onChildClick(ExpandableListView expandableListView,
                                        View view,
                                        int groupPosition,
                                        int childPosition, long id) {
                //Log.d("DEBUG", "submenu item clicked");
                Toast.makeText(MainActivity.this,
                        "Header: "+String.valueOf(groupPosition) +
                        "\nItem: "+ String.valueOf(childPosition), Toast.LENGTH_SHORT)
                        .show();
                view.setSelected(true);
                if (view_Group != null) {
                    view_Group.setBackgroundColor(Color.parseColor("#ffffff"));
                }
                view_Group = view;
                view_Group.setBackgroundColor(Color.parseColor("#DDDDDD"));
                mDrawerLayout.closeDrawers();
                return false;
            }
        });
        expandableList.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {
            @Override
            public boolean onGroupClick(ExpandableListView expandableListView, View view, int i, long l) {
                //Log.d("DEBUG", "heading clicked");
                return false;
            }
        });

    }

    private void prepareListData() {
        listDataHeader = new ArrayList<String>();
        listDataChild = new HashMap<String, List<String>>();

        // Adding data header
        listDataHeader.add("menu1");
        listDataHeader.add("menu2");
        listDataHeader.add("menu3");
        listDataHeader.add("menu4");
        listDataHeader.add("menu5");
        listDataHeader.add("menu6");
        listDataHeader.add("menu7");

        // Adding child data
        List<String> heading1 = new ArrayList<String>();
        heading1.add("Submenu");
        heading1.add("Submenu");
        heading1.add("Submenu");

        List<String> heading2 = new ArrayList<String>();
        heading2.add("Submenu");
        heading2.add("Submenu");
        heading2.add("Submenu");
        heading2.add("Submenu");

        List<String> heading3 = new ArrayList<String>();
        heading3.add("Submenu");
        heading3.add("Submenu");

        List<String> heading4 = new ArrayList<String>();
        heading4.add("Submenu");
        heading4.add("Submenu");

        List<String> heading5 = new ArrayList<String>();
        heading5.add("Submenu");
        heading5.add("Submenu");
        heading5.add("Submenu");

        List<String> heading6 = new ArrayList<String>();
        heading6.add("Submenu");
        heading6.add("Submenu");

        List<String> heading7 = new ArrayList<String>();
        heading4.add("Submenu");
        heading4.add("Submenu");

        listDataChild.put(listDataHeader.get(0), heading1);// Header, Child data
        listDataChild.put(listDataHeader.get(1), heading2);
        listDataChild.put(listDataHeader.get(2), heading3);
        listDataChild.put(listDataHeader.get(3), heading4);
        listDataChild.put(listDataHeader.get(4), heading5);
        listDataChild.put(listDataHeader.get(5), heading6);
        listDataChild.put(listDataHeader.get(6), heading7);
    }

    private void setupDrawerContent(NavigationView navigationView) {
        navigationView.setNavigationItemSelectedListener(
            new NavigationView.OnNavigationItemSelectedListener() {
                @Override
                public boolean onNavigationItemSelected(MenuItem menuItem) {
                    menuItem.setChecked(true);
                    mDrawerLayout.closeDrawers();
                    return true;
                }
            });
    }

    @Override
    public void onBackPressed() {
        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        if (drawer.isDrawerOpen(GravityCompat.START)) {
            drawer.closeDrawer(GravityCompat.START);
        } else {
            super.onBackPressed();
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    @SuppressWarnings("StatementWithEmptyBody")
    @Override
    public boolean onNavigationItemSelected(MenuItem item) {
        // Handle navigation view item clicks here.
        int id = item.getItemId();

        /*if (id == R.id.nav_camera) {
            // Handle the camera action
        } else if (id == R.id.nav_gallery) {

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

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

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

ExpandableListAdapter.java

import android.content.Context;
import android.graphics.Typeface;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.ExpandableListView;
import android.widget.ImageView;
import android.widget.TextView;

import java.util.HashMap;
import java.util.List;

/**
 * Created by Administrator on 9/1/16.
 */
public class ExpandableListAdapter extends BaseExpandableListAdapter {
    private Context mContext;
    private List<String> mListDataHeader; // header titles

    // child data in format of header title, child title
    private HashMap<String, List<String>> mListDataChild;
    ExpandableListView expandList;

    public ExpandableListAdapter(Context context,
                 List<String> listDataHeader,
                 HashMap<String,
                 List<String>> listChildData
    //        ,ExpandableListView mView
    )
    {
        this.mContext = context;
        this.mListDataHeader = listDataHeader;
        this.mListDataChild = listChildData;
        //this.expandList = mView;
    }

    @Override
    public int getGroupCount() {
        int i = mListDataHeader.size();
        //Log.d("GROUPCOUNT", String.valueOf(i));
        return i;
    }

    @Override
    public int getChildrenCount(int groupPosition) {
        return this.mListDataChild.get(
                this.mListDataHeader.get(groupPosition))
                .size();
    }

    @Override
    public Object getGroup(int groupPosition) {
        return this.mListDataHeader.get(groupPosition);
    }

    @Override
    public Object getChild(int groupPosition, int childPosition) {
        //Log.d("CHILD", mListDataChild.get(this.mListDataHeader.get(groupPosition))
        //        .get(childPosition).toString());
        return this.mListDataChild.get(
                this.mListDataHeader.get(groupPosition))
                .get(childPosition);
    }

    @Override
    public long getGroupId(int groupPosition) {
        return groupPosition;
    }

    @Override
    public long getChildId(int groupPosition, int childPosition) {
        return childPosition;
    }

    @Override
    public boolean hasStableIds() {
        return false;
    }

    @Override
    public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
        String headerTitle = (String) getGroup(groupPosition);
        if (convertView == null) {
            LayoutInflater infalInflater = (LayoutInflater) this.mContext
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = infalInflater.inflate(R.layout.listheader, null);
        }
        TextView lblListHeader = (TextView) convertView
                .findViewById(R.id.submenu);
        ImageView headerIcon = (ImageView) convertView.findViewById(R.id.iconimage);
        lblListHeader.setTypeface(null, Typeface.BOLD);
        lblListHeader.setText(headerTitle);
        //lblListHeader.setText(headerTitle.getIconName());
        headerIcon.setImageResource(MainActivity.icon[groupPosition]);
        return convertView;
    }

    @Override
    public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
        final String childText = (String) getChild(groupPosition, childPosition);

        if (convertView == null) {
            LayoutInflater infalInflater = (LayoutInflater) this.mContext
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = infalInflater.inflate(R.layout.list_submenu, null);
        }

        TextView txtListChild = (TextView) convertView
                .findViewById(R.id.submenu);

        txtListChild.setText(childText);

        return convertView;
    }

    @Override
    public boolean isChildSelectable(int groupPosition, int childPosition) {
        return true;
    }
}

list_submenu.xml

<?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="match_parent">
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="10dp"
        android:textColor="#000000"
        android:layout_marginLeft="44dp"
        android:textSize="14sp"
        android:id="@+id/submenu"/>
</LinearLayout>

listheader.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="2dp"
    android:orientation="vertical"
    xmlns:android="http://schemas.android.com/apk/res/android" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <ImageView
            android:layout_width="45dp"
            android:layout_height="45dp"
            android:paddingBottom="10dp"
            android:paddingLeft="10dp"
            android:paddingTop="10dp"
            android:id="@+id/iconimage"/>
        <TextView
            android:layout_width="match_parent"
            android:layout_height="45dp"
            android:padding="10dp"
            android:textColor="#000000"
            android:textSize="16sp"
            android:id="@+id/submenu"
            android:gravity="center_vertical" />
    </LinearLayout>

</LinearLayout>

activity_main.xml

<?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"
        android:fitsSystemWindows="true"
        app:headerLayout="@layout/nav_header_main">

        <ExpandableListView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@android:color/white"
            android:layout_marginTop="160dp"
            android:choiceMode="singleChoice"
            android:id="@+id/navigationmenu">
        </ExpandableListView>

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

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

Hope this will work and some other files are in this example... I think you can solve those matters... It will look like as you are wanted...

Sciuroid answered 2/9, 2016 at 16:8 Comment(1)
Why do you have two instances of DrawerLayout? I'm referring to the code from MainActivity.java. ThanksTitos
U
1

You can follow Priyank Patel answer above. Additionally, I wanted to hide the drop-down icon in front of the list item.

Just add android:groupIndicator="@null" to your ExpandableListView in xml tag.

<ExpandableListView
   android:id="@+id/navigationmenu"
   android:layout_width="wrap_content"
   android:layout_height="match_parent"
   android:groupIndicator="@null"
   android:layout_marginTop="192dp"
   android:background="@android:color/white">

</ExpandableListView>
Underscore answered 6/8, 2019 at 5:36 Comment(0)
S
1

You can do it by simple way without ExpandableListView

1- for showing down arrow u can customize menu item by actionLayout, also I'm giving unique id for each group to show divider line

**Media has 3 sub items

<item
    android:id="@+id/nav_media"
    android:title="Media"
    app:actionLayout="@layout/nav_arrow" />

<group
    android:id="@+id/media_group"
    android:checkableBehavior="single"
    android:visible="false">

    
        <item
            android:title="Media1"
            app:actionLayout="@layout/nav_arrow"
            />

        <item
            android:title="Media2"
            app:actionLayout="@layout/nav_arrow"
            />

        <item
            android:title="Media3"
            app:actionLayout="@layout/nav_arrow"
            />
</group>

2- this is nav_arrow.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="horizontal">

    <ImageView
        android:id="@+id/igv_arrow"
        android:layout_width="15dp"
        android:layout_height="15dp"
        android:layout_marginStart="5dp"
        android:gravity="center"
        android:layout_marginTop="16dp"
        android:layout_marginBottom="16dp"
        android:src="@drawable/ic_16_arrow_right"/>
</LinearLayout>

3- then in Activity

private boolean isMediaVisible= false;

         case R.id.nav_media:
                if (!isMediaVisible) {
                    menuItemArrow.setRotation(90f);//to rotating arrow to down
                    navigationView.getMenu().setGroupVisible(R.id.media_group, true);
                    isMediaVisible= true;
                } else {
                    menuItemArrow.setRotation(0f);
                    navigationView.getMenu().setGroupVisible(R.id.media_group, false);
                    isMediaVisible= false;
                }
                return;
Stickler answered 5/7, 2022 at 11:49 Comment(0)
M
-4

Thanks @Priyank and @atabek it relay helped me

when i completed this code it was working fine except the item click event and it was not showing selected item for that i made a small changes

in layout ExpandableListView i have added listSelector (http://developer.android.com/reference/android/widget/AbsListView.html#attr_android:listSelector)

    <ExpandableListView
        android:id="@+id/navigationmenu"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginTop="192dp"
        android:background="@android:color/white"
        android:choiceMode="singleChoice"
        android:listSelector="@color/colorAccent"
        />

and in activity instead of setting up the click listener to NavigationView changed to expandableList (http://developer.android.com/reference/android/widget/ExpandableListView.OnChildClickListener.html)

------
------
private void setupDrawerContent(NavigationView navigationView) {

    expandableList.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
        @Override
        public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {

            int index = parent.getFlatListPosition(ExpandableListView.getPackedPositionForChild(groupPosition, childPosition));
            parent.setItemChecked(index, true);

            Toast.makeText(MainActivity.this, "clicked " + listDataChild.get(listDataHeader.get(groupPosition)).get(childPosition).toString(), Toast.LENGTH_SHORT).show();
            mDrawerLayout.closeDrawers();

            return true;
        }
    });

    /*
    navigationView.setNavigationItemSelectedListener(
            new NavigationView.OnNavigationItemSelectedListener() {
                @Override
                public boolean onNavigationItemSelected(MenuItem menuItem) {
                    menuItem.setChecked(true);
                    mDrawerLayout.closeDrawers();
                    return true;
                }
            });
    */
}
------
------
Microwatt answered 14/12, 2015 at 11:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.