ExpandableListView on Android

      106 Comments on ExpandableListView on Android
ListView is pretty widely used. There are situations when you would like to group/categorize your list items. To achieve such a thing on Android, you would probably use the ExpandableListView. The data to the ExpandableListView is supplied by a special kind of adapter called the SimpleExpandableListAdapter which extends the BaseExpandableListAdapter.

As with any other widget on Android, you are free to customize the widgets as per your needs. Here, I will show how to create such a custom list adapter for the ExpandableListView.

For this example, I want to show a list of vehicles with their names. Also, I want to group them according to their category.

I have 4 classes.
1. Vehicle : The parent class for the rest.
2. Car: Extends the Vehicle class.
3. Bus: Extends the Vehicle class.
4. Bike: Extends the Vehicle class.

I have a method called getRandomVehicle(String name) which returns a random vehicle instance setting the name that I pass. The vehicle can be a Bus, Car or a Bike. Its completely random.

In the ExpandableListAdapter, (the custom adapter), there’s a method called addItem(Vehicle vehicle), which manages the groups and their children.

In the SampleActivity, I have initialized a blank ExpandableListAdapter and set it to the list view. Now, I start a thread, which gets a random vehicle after every 2 seconds, and adds it to the adapter, and calls the adapter to notify that the data has changed.

There are a few methods, in the ExpandableListAdapter, which you should go through carefully. I have two layout files, group_layout.xml and child_layout.xml which are used as the layout for the group views and the child views of the ExpandableListView.

There you go, you have a custom ExpandableListView. You can find the full source code for this example here, ready to run.

There are some more methods that you might be interested in, like, how to change the “arrow icon” for the group views(official doc link), or how to expand or collapse a group at will, or how to handle specific events like group collapsed or group expanded. Read the docs on ExpandableListView.

106 thoughts on “ExpandableListView on Android

  1. atur

    Hello Kumar,

    Thanks for posting your tutorials, they are very useful.

    I'm trying to implement CheckedTextView under ExpandableListView, however Checking a box in one group can cause a random box from another group to check or uncheck once I expand or Collapse a group, I'm using SimpleExpandableListAdapter, do I need to cutomise my own adapter? and do I need to keep track of each state of checkbox using something like SharedPreference?

    I'm new to Android and have no idea how to make a custom ExpandableListAdapter, what should I be looking at in order to solve the phenomenon above? getChildView()? and onGroupExpand/Collpase()?

    It will be greatly appreciated if you could give me a hint, thanks a lot in advance.

    Reply
  2. atur

    Thanks Kumar, I used SharedPreferences to keep track of the state of each checkbox and make sure the state is correct in getChildView(), thanks for the tip.

    Reply
  3. dev

    Kumar-
    Thanks for the post…helped tons getting my development going.
    But have a quick question-
    I have a ragged hierarchy of parents and children.
    In that there are some parents that have 5 children…and some parents have 0 children.

    The expandableListView displays the "Expand/Collpase" icon even if there are no children.

    Question-
    Is there a way to hide the icon for only those Parents(rows) that have no children?

    Reply
  4. Anonymous

    I'm a beginner in android,can i know why you avoid using them ?
    They seem practical to deal with user events.

    Reply
  5. Kumar Bibek

    Well, Normally, I would have a few more controls on the activity other that just the List. It could still work, but it's just a personal choice, I would say. 🙂

    Reply
  6. Pye Phyo Han

    Hi Kumar,
    I am really appreciates for your useful post. I have one question at below.
    How can i use custom font at this list view? Actually I have tried some coding at ExpandableListAdapter.java. I put like this inside "public View getGroupView"

    TextView txt = (TextView) findViewById(R.id.tvGroup);
    Typeface font = Typeface.createFromAsset(getAssets(), "Chantelli_Antiqua.ttf");
    txt.setTypeface(font);

    The Error is getAssets() is cannot use inside ExpandableListAdapter. If you don't mind, please give me some ideas. Thanks millions Bro!

    Reply
  7. Anonymous

    How can i add list view as child?? i would like to add n number of expandablelistview depending on the number of requirements..any suggestions on how to do this

    Reply
  8. Himanshu

    Hi All, I have a problem, i have made a expandable list, and i have a view on child list now i want access that view on Clicking event on parent list.
    Please help me.
    Thank you

    Reply
    1. Anonymous

      hi kumar how do you resolve "resource not found exception -resource is not a drawable"….i have used 4 png files .

      Reply
  9. Himanshu

    yes, when we expand the list then it shows the child list, and this child has some view,like image button. i have to access that image button on clicking of parent list.

    i want access that child's view on the following code

    expandedList.setOnGroupClickListener(new OnGroupClickListener()
    {

    @Override
    public boolean onGroupClick(ExpandableListView arg0, View arg1, int arg2, long arg3)
    {

    Toast.makeText(getBaseContext(), "Group clicked ", Toast.LENGTH_SHORT).show();

    return false;
    }
    });

    Reply
  10. Himanshu

    I have done this work, i have inflated the child_Layout inside the listener but it gives null pointer exception.
    i have added the following code inside the listener.

    LayoutInflater infalInflater = (LayoutInflater) context
    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View convertView = infalInflater.inflate(R.layout.child_row, null);

    ImageView tv = (ImageView) convertView
    .findViewById(R.id.imageView2);
    tv.setOnClickListener(new OnClickListener() {

    @Override
    public void onClick(View arg0) {
    Intent intent = new Intent(ExpList.this, DemoActivity.class);
    startActivity(intent);
    }
    });

    Reply
  11. Kumar Bibek

    Intent intent = new Intent(context, DemoActivity.class);

    You should be passing the context to the adapter, and use that context here like this.

    Send it to my mail if you want, but I can only check it by tonight.

    Reply
  12. Anonymous

    Sir, I have a problem that I want to copy videos from my Desktop Pc's MyVideos Directory to sdcard of android emulator through code. But I unable to do that. I had searched it many times on the web but can't find the exact solution. Can you help me regarding this?

    Reply
  13. Anonymous

    Hello Kumar,
    I have a problem in Expandable list. I want to access Child_row's xml file in parent list click event.could u provide the code for the same.
    Thanks.

    Reply
  14. Himanshu

    @Kumar: Actually, I have a problem in Expandable list, when we expand any parent group, it has child list, and in every child row it has a button. but i am unable to give event to that button.
    so i was asking that can we make and expandable list with the help of simple list view??

    please give me right solution to do this task.
    how it can be done? is there any alternative ??

    Reply
  15. Anonymous

    Sir, I need to set the twolinelistitem to ExpandableListview as child, Is it possible? if possible please send me the code

    Reply
  16. Anonymous

    sir can you plz tell me how can i place deferent images on the each groupview of expandable listview….

    Reply
  17. E-Nature

    Thanks for that tutorial!
    I was wondering – is it also possible to have a double-expandable list? My situation is as follows:

    -SystemPlatform-Object
    — Game-Object
    —— Cheat-Object
    —— Cheat-Object
    —— Cheat-Object
    — Game-Object
    —— Cheat-Object
    —— Cheat-Object
    — Game-Object
    —— Cheat-Object
    -SystemPlatform-Object
    — Game-Object
    —— Cheat-Object
    — Game-Object
    —— Cheat-Object
    —— Cheat-Object
    —— Cheat-Object
    — Game-Object
    —— Cheat-Object
    etc.

    Could you give me a hint how I could implement something like this? I want the SystemPlatform objects to be expandable (that already works if I use your tutorial) but in the childs of the Game objects also have expandable children.

    Thanks a lot for your help!

    Reply
  18. Anonymous

    Hi Kumar,
    I want to develop similar ExpandableListview to an Accordion Menu. When I click a parent bar it extracts. If the different is this:
    A parent's child has a list but other parent's child has a image etc.
    How do I do this?
    Thanks

    Reply
  19. Arunkumar

    Thanks for that tutorial!

    -SystemPlatform-Object
    — Game-Object
    —— Cheat-Object
    —— Cheat-Object
    —— Cheat-Object
    — Game-Object
    —— Cheat-Object
    —— Cheat-Object
    — Game-Object
    —— Cheat-Object
    -SystemPlatform-Object
    — Game-Object
    —— Cheat-Object
    — Game-Object
    —— Cheat-Object
    —— Cheat-Object
    —— Cheat-Object
    — Game-Object
    —— Cheat-Object
    etc.

    did you tried this………..

    Reply
  20. Van

    Great Tutorial! Thanks!

    I would like to use this using a database back end. I have defined a cursor to populate the list. Specifically, if I use a text field to display the item list (adapter.addItem()), how can retrieve the database record number?

    Would you provide a suggestion how to 'toast' the database record number.

    Reply
  21. linisax

    Thanks for posting this tutorial. It was of immense help. However, I found a small problem in the main.xml. While declaring expandable list, android requires the use of the id that is declared in android just as we use for list:

    I kept getting runtime exceptions since I was having id as listView.

    Reply
  22. Kumar Bibek

    @linisax: If your activity extends ExpandableListActivity, you will need to have the id different, in the android namespace, else, if your activity extends the basic activity, this sample would run fine.

    Reply
  23. linisax

    Thanks for that small detail. It is easy to over-look it.
    I found a new problem with expandablelistview and adapters. So I retrieve the values for the group arraylist and the children arraylist using a thread. However, simply calling notifyDataSetChanged() on the adapter did not refresh my listview. It showed as empty. (my code is laid out very similar to your example. The only difference is the data modelling which is coming from a server in my case).

    So I wrote a helper function in the adapter class that manully updated the group and children arraylists to the values received from server. After that calling notifyDataSetChanged(), refreshed my list. I am not sure if this is a good programming practice but it worked.

    Reply
  24. Martin

    Thanks you, Kumar. Your example has been extremely helpful to me. I needed a list view years and months. Since every year has the same months (of course!) there was no need to supply the months to the adapter so I simplified it to this:

    public class MyExpandableMonthListAdapter extends BaseExpandableListAdapter {
    private String[] children = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" };

    @Override
    public boolean areAllItemsEnabled() {
    return true;
    }

    private ArrayList groups;

    public MyExpandableMonthListAdapter(Context context, ArrayList groups) {
    this.groups = groups;
    }

    public Object getChild(int groupPosition, int childPosition) {
    return children[childPosition];
    }

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

    public int getChildrenCount(int groupPosition) {
    return children.length;
    }


    }

    And then I initialize it with:

    years = new ArrayList(Arrays.asList( "2011","2010","2009","2008" ));
    MyExpandableMonthListAdapter myAdapter = new MyExpandableMonthListAdapter(this, years);

    Reply
  25. Ani

    Kumar,

    I only have 1 child view for each group view, which is inflated from a layout .xml file. I wish to animate the child view so that when the child item is displayed, the list item below it slids down. I am trying the following, but the animation doesn't show as expected. I have added the following to the getChildView(), just before I return the child view:

    Animation anim = AnimationUtils.loadAnimation(
    MyExpandableList.this, R.anim.translate);
    v.setAnimation(anim);

    Here's is my translate.xml:

    Thanks for your help.

    Ani.

    Reply
  26. Kumar Bibek

    Umm, There's no multiple inheritance.

    But, your activity could extend the TabActivity, and use the ExpandableListViews in layouts directly. So, in this case, you need to extend the ExpandableListActivity.

    Reply
  27. Marc

    Hi, thanks for the tutorials, it's great having people like yourself help everyone else.

    This expandable listview is similar to what i'm looking for but doesnt quite have the functionality that i'm after. I have a custom slidingdrawer class that i've got to a stage where it acts how i would like however i'm now looking to stack them, so that the handles appear one on top of eachother, almost acting like an accordion menu. Any tips on where to look to get this to work? I know that there are issues with the containing framelayout etc =s

    Reply
  28. Anonymous

    Hi All 🙂
    Have you any idea how to (if it is possible) develop an expandable listView where each group header stays pinned to the top until it is pushed up by the next group view?
    @Agamousy

    Reply
  29. rakendu

    Hi, Thanks for the post. really helpful. Can you tell me ow u replaced the icon(the icon which shows that the list is expanded or not) with ur custom icon? and the svn link for readonly dosen seem to work. Please help

    Reply
  30. Bluemercury

    Hi there all! How do you deal with having a group header but no childs???im using this example for building a dialog with the expandable list and its working fine, except when i try to expand the group with no childs i get an error regarding the children arraylist of arraylist. in this case there's no childs in position 3, so it gives an out of bounds exception. Also is there a way to prevent the icon to change/ and the position to expand since thre's no childs?

    regards,

    Reply
  31. Bluemercury

    Hi there all! How do you deal with having a group header but no childs???im using this example for building a dialog with the expandable list and its working fine, except when i try to expand the group with no childs i get an error regarding the children arraylist of arraylist. in this case there's no childs in position 3, so it gives an out of bounds exception. Also is there a way to prevent the icon to change/ and the position to expand since thre's no childs?

    regards,

    Reply
  32. Bluemercury

    IS there a way to deal with groups with no childs??this example gives an outofbound exception in the children arraylist of arraylist in the adapter if you try to exapnd a ground that has no childs. Also is there a way to prevent the icon to change position and also prevent to expand in this case at all?

    regards,

    Reply
  33. Bluemercury

    Im using the adapter in the code you posted but its not doing that…Also is there a way to manually do the expanding/collapsing as in define a button do that instead of pressing any area of the group row???i want to also select the group as an option like the childs….

    Reply
  34. Anonymous

    has anyone tried that with the code successfullyu. please can anyone post thier running code here. the code available on the site recomended dosnt provide a gud class structure.

    Reply
  35. Rac

    I have used BaseExpandableListAdapter for a project.We have a requirement to highlight group row selection.so that user can see for himself the row selected.How is this possible

    Reply
  36. Rac

    I have used BaseExpandableListAdapter for a project.We have a requirement that the Group row should remain hightlighted to show user his selection.How is this possible

    Reply
  37. Anonymous

    Hi, I have used the above code to make an expandable list view..Although , the code attaches drawlable objects to the parent group..My aim to to make a an expandableview for a form , i.e , the children to be attached to each group is an .xml layout. How do I do that? Any suggestions please?

    Reply
  38. Andi

    Hi Kumer, really nice tutorial. I have only one Question. My Ex-Listview doesnt show groups with no entries. Do you have any hint for me how to display them? Thank you so far!

    Reply
  39. Anonymous

    Hi Kumar ,

    I have 5 groups in my expandableviewlist. I want to populate the child of each group with a different XML layout. Is that possible?Hope it is clearer now..

    Reply
  40. Krishna Veni

    Hi this is very nice tutorials…thanks for post this tutorial..i have one doubts.
    I have a problem , ı want to add different child for respective groups in expandableList like that;

    – OrderInfo
    – payment_method
    – total
    – CustomerInfo
    – firstname
    – lastname
    i know Is it possible?…but i can't develop this..can anyone give me some sample code please ?or give me some idea…

    Reply
  41. Lefteris

    Hello Kumar,

    this is a very nice post.

    However I am trying to understand how I can animate the expand/collapse of the group. So, I want to touch on the group and expand the list but with animation. Similarly, when tapping again on the group to collapse but with animation.

    Do you have any idea of how to achieve this?

    Thanks

    Reply
  42. Keyur

    Hello Sir,

    Its very nice tutorial on ExpandableListView and very well explained. But I am in need of your help in this. I am having 1 expandablelistview in my app with only 1 group. I am displaying review and ratings inside it. I follow your tutorials but somehow as my case is different my list is not displayed. It only shows me the header of the expandablelistview, when i click to see the details its not calling the childView method of the adapter. Here is the link of SO of my question with full details and source code. If you can please have a look on it once and help me then it would be very great for me.

    Regards
    Keyur

    Reply
  43. Anonymous

    Hey Kumar,

    I am quite new to android programming, and there are so many listeners i don`t know how to pick the right one.

    i want each parend zu have a button, which adds a child node to its sektion.

    but wen i add a onclicklistener to the button, i don`t know how to get the section where the button was 🙁

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *