ExpandableListView and the NavigationDrawer

daniel_c05 picture daniel_c05 · Aug 12, 2013 · Viewed 7.4k times · Source

I am having a pretty strange issue. My logic is simple, my app uses a NavigationDrawer for main application navigation, and due to the complexity of the options available, I want to use an ExpandableListViev to nest some navigation items.

The issue? Simple too: The list of items loads on the drawer; however, they don't expand to show the children.

The Question Is there any reason it wouldn't expand? Should I use a different UI widget for this?

Some Notes: I added the same code on a different Activity, but instead of hosting the ExpandableListViev on the drawer, I had it added on a simple LinearLayout as the only element, and it does work well there.

My Layout for the Activity:

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

<ExpandableListView
        android:id="@+id/left_drawer"
        android:layout_width="240dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:background="@color/secondary_color_holo"/>

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

The Activity code:

private DrawerLayout mDrawerLayout;
private ExpandableListView mDrawerList;
private ExpandableDrawerAdapter mDrawerAdapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
    mDrawerList = (ExpandableListView) findViewById(R.id.left_drawer);
    // set up the drawer's list view with items and click listener
    mDrawerAdapter = new ExpandableDrawerAdapter(this);
    mDrawerList.setAdapter(mDrawerAdapter);
    mDrawerList.setOnGroupClickListener(new DrawerGroupClickListener());
    mDrawerList.setOnChildClickListener(new DrawerChildClickListener());
}

And finally a very simple adapter:

public class ExpandableDrawerAdapter extends BaseExpandableListAdapter {

private static final int CAMPAIGNS = 0;
private static final int CONVERSIONS = 1;
private static final int MYACCOUNT = 2;

private LayoutInflater mInflater;
private String[] mainNavItems, campaignNavItems, myAccountNavItems;

public ExpandableDrawerAdapter (Activity context) {
    this.mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    this.mainNavItems = context.getResources().getStringArray(R.array.main_nav_items);
    this.campaignNavItems = context.getResources().getStringArray(R.array.campaigns_nav_items);
    this.myAccountNavItems = context.getResources().getStringArray(R.array.my_account_nav_items);
}

public Object getChild(int groupPosition, int childPosition) {

    switch (groupPosition) {
        case CAMPAIGNS:
            return campaignNavItems[childPosition];
        case MYACCOUNT:
            return myAccountNavItems[childPosition];
        default:
            return "";
    }
}

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

public View getChildView(final int groupPosition, final int childPosition,
                         boolean isLastChild, View convertView, ViewGroup parent) {

    if (convertView == null) {
        convertView = mInflater.inflate(R.layout.drawer_child_list_item, null);
    }

    TextView childText = (TextView) convertView.findViewById(R.id.drawer_child_list_item_text);
    childText.setText((String) getChild(groupPosition, childPosition));

    return convertView;
}

public int getChildrenCount(int groupPosition) {
    switch (groupPosition) {
        case CAMPAIGNS:
            Constants.logMessage("Children for group position: " + groupPosition + " are: " + campaignNavItems.length);
            return campaignNavItems.length;
        case CONVERSIONS:
            Constants.logMessage("Children for group position: " + groupPosition + " are: " + 0);
            return 0;
        case MYACCOUNT:
            Constants.logMessage("Children for group position: " + groupPosition + " are: " + myAccountNavItems.length);
            return myAccountNavItems.length;
        default:
            return 0;
    }
}

public Object getGroup(int groupPosition) {
    return mainNavItems[groupPosition];
}

public int getGroupCount() {
    return mainNavItems.length;
}

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

public View getGroupView(int groupPosition, boolean isExpanded,
                         View convertView, ViewGroup parent) {

    if (convertView == null) {
        convertView = mInflater.inflate(R.layout.drawer_list_item,
                null);
    }

    TextView groupText = (TextView) convertView.findViewById(R.id.drawer_list_item_text);
    groupText.setText((String) getGroup(groupPosition));
    return convertView;
}

public boolean hasStableIds() {
    return true;
}

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

Answer

user picture user · Aug 15, 2013

As I said in my comment, make sure that you return false from the DrawerGroupClickListener that you set on the ExpandableListView. If you return true from the listener's onGroupClick() callback this will block the collapse/expand action as the event is considered handled.