Thursday, June 9, 2011

Hiding group indicator for empty groups

Another topic that keeps returning on this blog is the expandable list view. It seems those troublesome expandable lists always have some surprises in store. This time I ran into the issue of group indicators and empty groups.

Group indicators are those small arrows in front of the group rows that indicate, whether the group is expanded or collapsed. Trouble is that those indicators are always visible, even if the group is empty. This misleads users who think that they can expand the group. The group indeed expands but as it is empty, no child rows appear which can be extremely annoying.

Some internet sources propose wizardry with the variable drawable that backs the group indicator. If you follow the advice, the group indicator will disappear for all the collapsed groups (even for those which have child rows). This surprising behaviour is by design. Comment in the source of ExpandableListView says: "[if] the group is collapsed so we consider it empty for performance reasons". The method where this behaviour is wired in is private, it is not possible to overload it by subclassing ExpandableListView.

Fortunately the solution is very simple, even if a bit tricky. We will completely disable the group indicator logic in ExpandableListView and provide our own indicator from the adapter backing the expandable list. The group indicator is disabled by setting it to a transparent color in main.xml.

android:groupIndicator="@android:color/transparent"

Then we override getGroupView in the adapter (this time it was a SimpleExpandableListAdapter but the method works for any adapter). We had to manually add an ImageView to the group layout - this is normally done automagically by ExpandableListView but we have just disabled that functionality. Once getGroupView returns the group row, we post-manipulate the ImageView that acts as group indicator considering the child count for the group beside its expanded/collapsed state. This unfortunately means that you have to have custom expanded/collapsed icons in your program - those icons are extremely ugly in the example program, I leave it to you as a homework to beautify them.

16 comments:

I'm a community leader on a network of developer websites. I really liked your blog content and thought you might be interested in some extra exposure on our sites. Send me an email at ross [at] dzone [dot] com and I can explain all the details.

This is a great program, but I cannot get the second tier indicators to be transparent. Could you upload some completed code with the fixes for the indicators? Or maybe post snippets so I know exactly what to change? I would appreciate it.

Perhaps my word choice is poor. I'm looking for a solution to your last paragraph:

"...Once getGroupView returns the group row, we post-manipulate the ImageView that acts as group indicator considering the child count for the group beside its expanded/collapsed state. This unfortunately means that you have to have custom expanded/collapsed icons in your program - those icons are extremely ugly in the example program, I leave it to you as a homework to beautify them."

I don't follow. Even after I make the first arrow transparent, I can't get the send group's arrow transparent.

Anonymous, what was the image that you made transparent? res/group_row.xml refers to expander_group drawable which is a variable image (in res/drawable/expander_group.xml). This variable image forks to two real images based on open/closed state, expander_ic_maximized.png and expander_ic_minimized.png. Which one did you change?

About the blog

This blog is a personal diary about my adventures with the Google Android platform. I write it in the hope that others may find my experiences useful but please, beware. The blog is created as I gain experience about the platform myself so errors, omissions, etc. may be found in the entries.