Multilevel, expandable lists are useful user interface elements and Android does support two-level expandable lists. This fact would not be worth a blog entry if there were no traps using the widget.
Click here to download the example program.
The example program implements a simple, two-level expandable list to display color shade information.
The first thing to note is that our Activity extends android.app.ExpandableListActivity. Otherwise setting up the list is pretty similar to ordinary ListActivity classes. The tricky part is the android.widget.SimpleExpandableListAdapter.
SimpleExpandableListAdapter expListAdapter =
new SimpleExpandableListAdapter(
this,
createGroupList(), // groupData describes the first-level entries
R.layout.child_row, // Layout for the first-level entries new
String[] { "colorName" }, // Key in the groupData maps to display
new int[] { R.id.childname }, // Data under "colorName" key goes into this TextView createChildList(), // childData describes second-level entries
R.layout.child_row, // Layout for second-level entries
new String[] { "shadeName", "rgb" }, // Keys in childData maps to display
new int[] { R.id.childname, R.id.rgb } // Data under the keys above go into these TextViews
);
First of all, this adapter requires somewhat complicated (although pretty well-documented) data structures. There are two of them, one describing the first-level group elements, the other describing the second-level string elements.
Here is the first one:
List->Map
Every map describes one first-level group element. The keys in the Map are arbitrary but are specified for SimpleExpandableListAdapter so that it can map the keys in the Map to widget IDs. In our case, the data under key name "colourName" will be set as the value of the TextView with "childname" ID.
The second one is a bit more complicated.
List->List->Map
Every entry in the first List represents a group. Entries in the second List represent entries of the group and each such entry is a Map that describes one child, similarly to the description of groups. In our case, the child Map contains two entries (keys "shadeName" and "rgb") that go to TextViews ("childname" and "rgb").
So far so good. Unfortunately, SimpleExpandableListAdapter has its tricks. First of all, the adapter takes the description of one row from a layout (child_row in our case, located under res/layout/child_row.xml). When the adapter draws the expand button onto the row, it does not consider the content of the row, it simply draws the button over the row. That's the reason child_row.xml defines generous left padding for the first TextView. While this behaviour can be considered just an oddity, the fact that SimpleExpandableListAdapter must be created with identical views for first- and second-level lines is a plain bug that existed at least since m3-rc37a. Having group- and child rows with different styles is a cool and useful feature that is supported by SimpleExpandableListAdapter but does not work.
Replace this fragment:
R.layout.child_row, // Layout for the first-level entries
new String[] { "colorName" }, // Key in the groupData maps to display
new int[] { R.id.childname }, // Data under "colorName" key goes into this TextView
with this one:
R.layout.group_row, // Layout for the first-level entries
new String[] { "colorName" }, // Key in the groupData maps to display
new int[] { R.id.groupname }, // Data under "colorName" key goes into this TextView
and you will see, how the expandable list gets confused.
Tuesday, May 13, 2008
Subscribe to:
Post Comments (Atom)
26 comments:
You sure helped me a lot with this example ;)
I think that you could use the group_row layout for the first-level elements but when I test it it acts weird ..
I just wanted to know whether you have implemented a customised SimpleExpandedListAdapter.If yes,please do share that as well
Thanks
This example was excellent and helpful.
The next step would be handling a click event on the child items.
Ed it should be like you say (at least one would expect it) but replacing group stuff with children stuff actually makes the code work. Otherwise it doesn't..
Gabor, I haven't worked with Android since I posted here .. If I work on something I will let you know
Thank you for this example! It is really tricky ... i think "Simple" is the wrong name for this adapter, your tutorial helped me out of some trouble.
Hi! to all
Please help me, how to apply the animations to all subtypes of views and lists.
Thanx in advance
Jetti, does this help?
Thanx Gabor Paller!
Today i will try this.
Thank you very much! Veeeery useful.
could you please guide me if i want to add multichoice functionality with this example what should i do??
i want expandable list with checkboxes too
waiting for you reply.
thanks in advance.
I tried to apply checkboxes to expandable list,but it is not worked for me...
MaDhu Cry, try this post.
Anonymous, try this line in onCreate:
getExpandableListView().setChoiceMode( ListView.CHOICE_MODE_MULTIPLE );
This is only two level of expansion. How can I do a multi-level expansion list. My requirement is of 4 level.
Excellent Code !!!! thanx
"This is only two level of expansion. How can I do a multi-level expansion list. My requirement is of 4 level. "
ExpandableListView can only do 2 levels. If you want more, you have to write your own widget. The source of the platform's ExpandableListView is a good starting point.
This is a great guide that helped me a lot!!
BTW, the bug you talked about appears to be fixed. I did the code replacement and it worked fine.
Hi all this is good one i want to know one thing.
can we access childname xml file on public boolean onGroupClick(ExpandableListView arg0, View arg1,
int arg2, long arg3)method???
thank you.
Hi,
Actually in my list,I had many childs,and I want to apply separate background for clicked child for differentiating.Is it possible to apply?
The bug with different layouts seem to be solved. Tried it in the emulator with android version 2.2 and it looks good
Yah I got it, Thanks Linda..
Hey
i want to collapse the grey when i click blue or any other group and vice versa how to achieve it any help
In ExpandListVIew API, We have setOnGroupCollapseListener and setOnChildCollapseListener. And by using these, we can store previous clicked(opened) group item and use collapseGroup(groupID); we can achieve this. For Clarity please go through the ExpandableListView API..
Thanks
is it possible to have more than 2 levels of sublist because i need 5 levels of hierarchy. pls help
Post a Comment