Download Code

Android ExpandableListView Multi Level Example

In android expandablelistview multi level tutorial you will learn how to create android ExpandableListView multi level.You can learn about Expandable ListView from previous tutorial.

Create new android expandablelistview multi level application project.Go to activity_main.xml and add Expandable ListView.

android expandablelistview multi level,expandable

Create new layout for Parent Group header(first_group.xml).Add textview in this layout.

android expandablelistview multi level,expandable

Next create new layout for Sub Group and Child items(children.xml).

android expandablelistview multi level,expandable

Next go to your MainActivity.java class.Set Adapter of setting list to expandable listview.

MainActivity.java

package developer.expandablethreelevel;

import android.support.v7.app.ActionBarActivity;
import android.app.Activity;
import android.app.ExpandableListActivity;
import android.app.ListActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;


public class MainActivity extends ExpandableListActivity {
	static final String listPhone[][][][] = 
		{
		{ // Samsung
			{  // Galaxy
				{ "Samsung", "Galaxy" },
				{ "Galaxy","S3" },
				{ "Galaxy","S4" }
			},
			{  // J Series
				{ "Samsung", "J Series" },
				{ "Samsung Galaxy","J3" }
			}
		},
		{ // IPhone
			{  // IPhoneTab
				{ "IPhone", "IPhoneTab" },
				{ "Tablet","Itab" }
			},
			{  // ICellPhone
				{ "IPhone", "ICellPhone" },
				{ "iPhone","4S" },
				{ "iPhone","5S" }
			}
		},
		{ // BlackBerry
			{  // Phone
				{ "BlackBerry", "Phone" },
				{ "Berry","One" },
				{ "Berry","Two" }
			},
			{  // BlackBerryTab
				{ "BlackBerry", "BlackBerryTab" },
				{ "BerryTab","One" }
			}
		},
		{ // Sony Ericson
			{  // SonyPhone
				{ "Sony Ericson", "SonyPhone" },
				{ "sonyPhone","One" }
			},
			{  // SonyTab
				{ "Sony Ericson", "SonyTab" },
				{ "sonyTab","One" },
				{ "sonyTab","Two" }
			}
		}
		};
	private phoneExpandableListAdapter phonelist;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		phonelist = new phoneExpandableListAdapter(this,getExpandableListView(),listPhone);
		setListAdapter(phonelist);
	}


}

phoneExpandableListAdapter.java

package developer.expandablethreelevel;

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

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.TextView;

public class phoneExpandableListAdapter extends BaseExpandableListAdapter {

	private MainActivity mainActivity;
	private String listPhone[][][][];
	private LayoutInflater inflater;
	private ExpandableListView expandableListView;
	private handleExpandableListView listViewManager[];
	private String KEY_PHONE_NAME="phoneName";
	private String VERSION = "version";
	private String MODEL = "model";

	public phoneExpandableListAdapter(MainActivity mainActivity,
			ExpandableListView expandableListView, String[][][][] listphone) {
		// TODO Auto-generated constructor stub
		this.mainActivity = mainActivity;    // context
		this.expandableListView = expandableListView;   // expandable listview
		this.listPhone = listphone;                        // list of phone
		inflater = LayoutInflater.from(mainActivity);
		listViewManager = new handleExpandableListView[listPhone.length];
	}

	@Override
	public int getGroupCount() {
		// TODO Auto-generated method stub
		return listPhone.length;
	}

	@Override
	public int getChildrenCount(int groupPosition) {
		// TODO Auto-generated method stub
		return 1;
	}

	@Override
	public Object getGroup(int groupPosition) {
		// TODO Auto-generated method stub
		return listPhone[groupPosition][0][0][0];
	}

	@Override
	public Object getChild(int groupPosition, int childPosition) {
		// TODO Auto-generated method stub
		return listPhone[groupPosition][childPosition];
	}

	@Override
	public long getGroupId(int groupPosition) {
		// TODO Auto-generated method stub
		return (long)(groupPosition*1024);
	}

	@Override
	public long getChildId(int groupPosition, int childPosition) {
		// TODO Auto-generated method stub
		return (long)(groupPosition*1024+childPosition);
	}

	@Override
	public boolean hasStableIds() {
		// TODO Auto-generated method stub
		return true;
	}

	@Override
	public View getGroupView(int groupPosition, boolean isExpanded,
			View convertView, ViewGroup parent) {
		// TODO Auto-generated method stub
		View v = null;
		if( convertView != null )
			v = convertView;
		else
			v = inflater.inflate(R.layout.first_group, parent, false); 
		String gt = (String)getGroup( groupPosition );
		TextView phoneGroup = (TextView)v.findViewById( R.id.groupname );
		if( gt != null )
			phoneGroup.setText( gt );
		return v;
	}

	@Override
	public View getChildView(int groupPosition, int childPosition,
			boolean isLastChild, View convertView, ViewGroup parent) {
		// TODO Auto-generated method stub
		View view=null;
		if(listViewManager[groupPosition]!=null){
			view = listViewManager[groupPosition];
		}
		else{
			handleExpandableListView handle = new handleExpandableListView(mainActivity);
			handle.setRows(calculateRowCount(groupPosition,null));
			handle.setAdapter(
					new handleSimpleExpandableListAdapter(
							mainActivity,
							createGroupList(groupPosition),
							R.layout.children,
							new String[]{ KEY_PHONE_NAME},
							new int[] { R.id.childname },
							createChildList(groupPosition),
							R.layout.children,
							new String [] {VERSION,MODEL},
							new int[] { R.id.childname, R.id.version }
							)
					);
			handle.setOnGroupClickListener(new Level2GroupExpandListener( groupPosition ));
			listViewManager[groupPosition] = handle;
			view = handle;
		}
		return view;
	}

	private List createGroupList(int groupPosition) {
		// TODO Auto-generated method stub
		ArrayList result = new ArrayList();
	    for( int i = 0 ; i < listPhone[groupPosition].length ; ++i ) {
	        HashMap m = new HashMap();
	        m.put( KEY_PHONE_NAME,listPhone[groupPosition][i][0][1] );
	    	result.add( m );
	    }
	    return (List)result;
	}
	
	private List createChildList(int groupPosition) {
		// TODO Auto-generated method stub
		ArrayList result = new ArrayList();
	    for( int i = 0 ; i < listPhone[groupPosition].length ; ++i ) {
	    	// Second-level lists
	        ArrayList secList = new ArrayList();
	        for( int n = 1 ; n < listPhone[groupPosition][i].length ; ++n ) {
	            HashMap child = new HashMap();
		        child.put( VERSION, listPhone[groupPosition][i][n][0] );
	            child.put( MODEL, listPhone[groupPosition][i][n][1] );
		        secList.add( child );
	        }
	        result.add( secList );
	    }
	    return result;
	}

	

	private int calculateRowCount(int groupPosition, ExpandableListView object) {
		// TODO Auto-generated method stub
		 int level2GroupCount = listPhone[groupPosition].length;
	        int rowCtr = 0;
	        for( int i = 0 ; i < level2GroupCount ; ++i ) {
	            ++rowCtr;       // for the group row
				if( ( object != null ) && ( object.isGroupExpanded( i ) ) )
					rowCtr += listPhone[groupPosition][i].length - 1;	// then add the children too (minus the group descriptor)
	        }
			return rowCtr;
	}

	@Override
	public boolean isChildSelectable(int groupPosition, int childPosition) {
		// TODO Auto-generated method stub
		return true;
	}
	public void onGroupCollapsed (int groupPosition) {} 
	public void onGroupExpanded(int groupPosition) {}

	// expandable listview expand to subchild view
	class Level2GroupExpandListener implements ExpandableListView.OnGroupClickListener {
		
		private int level1GroupPosition;
		public Level2GroupExpandListener( int level1GroupPosition ) {
			this.level1GroupPosition = level1GroupPosition;
		}

       	public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) {
       		if( parent.isGroupExpanded( groupPosition ) )
            	parent.collapseGroup( groupPosition );
        	else
           		parent.expandGroup( groupPosition );
			if( parent instanceof handleExpandableListView ) {
				handleExpandableListView dev = (handleExpandableListView)parent;
				dev.setRows( calculateRowCount( level1GroupPosition, parent ) );
			}
           	
			expandableListView.requestLayout();
          	return true;
     	}

		
	}
	
	
}

handleExpandableListView.java

package developer.expandablethreelevel;

import android.content.Context;
import android.util.Log;
import android.view.View;
import android.widget.ExpandableListView;

public class handleExpandableListView extends ExpandableListView {
    public handleExpandableListView( Context context ) {
        super( context );
    }

	public void setRows( int rows ) {
		this.rows = rows;
		Log.d( LOG_TAG, "rows set: "+rows );
	}

    protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure( widthMeasureSpec, heightMeasureSpec );
    	setMeasuredDimension( getMeasuredWidth(), rows*ROW_HEIGHT );
        Log.d( LOG_TAG, "onMeasure "+this+
                        ": width: "+decodeMeasureSpec( widthMeasureSpec )+
                        "; height: "+decodeMeasureSpec( heightMeasureSpec )+
                        "; measuredHeight: "+getMeasuredHeight()+
                        "; measuredWidth: "+getMeasuredWidth() );
    } 

    protected void onLayout (boolean changed, int left, int top, int right, int bottom) {
        super.onLayout( changed, left,top,right,bottom );
        Log.d( LOG_TAG,"onLayout "+this+": changed: "+changed+"; left: "+left+"; top: "+top+"; right: "+right+"; bottom: "+bottom );
    }
 
    private String decodeMeasureSpec( int measureSpec ) {
        int mode = View.MeasureSpec.getMode( measureSpec );
        String modeString = "<> ";
        switch( mode ) {
            case View.MeasureSpec.UNSPECIFIED:
                modeString = "UNSPECIFIED ";
                break;

            case View.MeasureSpec.EXACTLY:
                modeString = "EXACTLY ";
                break;

            case View.MeasureSpec.AT_MOST:
                modeString = "AT_MOST ";
                break;
        }
        return modeString+Integer.toString( View.MeasureSpec.getSize( measureSpec ) );
    }

	private static final int ROW_HEIGHT = 20;
    private static final String LOG_TAG = "handleExpandableListView";
	private int rows;
}

handleSimpleExpandableListAdapter.java

package developer.expandablethreelevel;

import java.util.List;
import java.util.Map;

import android.content.Context;
import android.database.DataSetObserver;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListAdapter;
import android.widget.SimpleExpandableListAdapter;

public class handleSimpleExpandableListAdapter extends SimpleExpandableListAdapter {

	public handleSimpleExpandableListAdapter(Context context,
			List<? extends Map<String, ?>> groupData, int groupLayout,
			String[] groupFrom, int[] groupTo,
			List<? extends List<? extends Map<String, ?>>> childData,
			int childLayout, String[] childFrom, int[] childTo) {
		super(context, groupData, groupLayout, groupFrom, groupTo, childData,
				childLayout, childFrom, childTo);
		// TODO Auto-generated constructor stub
	}


	public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
        View v = super.getChildView( groupPosition, childPosition, isLastChild, convertView, parent );
        Log.d( LOG_TAG, "getChildView: groupPosition: "+groupPosition+"; childPosition: "+childPosition+"; v: "+v );
        return v;
    }

    public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
        View v = super.getGroupView( groupPosition, isExpanded, convertView, parent );
        Log.d( LOG_TAG, "getGroupView: groupPosition: "+groupPosition+"; isExpanded: "+isExpanded+"; v: "+v );
        return v;
    }

    private static final String LOG_TAG = "handleSimpleExpandableListAdapter";
	

}

Run your android expandablelistview multi level application project.

android expandablelistview multi level,expandable

that’s it for this android expandablelistview multi level tutorial.

Thanks.