September 2, 2014

Dev Tools: Customizing ExpandableListView

expandable_listviewI’m using ExpandableListView in my app and one of the complaints I got from users was that when the list item is expanded it’s hard to visually distinguish where the child item ends and next group item begins. Since that is out-of-the-box behavior I decided to modify it to something more user-friendly. My task seems easy enough – all I wanted to do was to change child list item background to lighter shade of grey hence creating visual separation between the parent (group) item and collapsible child list. However, how often is the case with Android doing that turned out to be not so easy so I would like to share my experience.

I use two layouts: item_group.xml and item_child.xml to inflate the list items in ExpandableListView#getGroupView and ExpandableListView#getChildView. So my initial plan was to simply set the top level LinearLayout‘s background in item_child.xml to the color I wanted. It worked but with unpleasant side effect: all my highlighting was gone. The child item will not change color on press or  on selected so I had to work with selectors to create background drawable that would satisfy my need. Here I will outline the steps:

  1. Create list_background.xml file in /res/drawable. You can name that file something else
  2. Set background of your child item layout to the drawable above android:background="@drawable/list_background"

Here’s complete code for list_background.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true" android:state_enabled="true"
        android:drawable="@drawable/list_highlight_active" />
    <item android:state_enabled="true" android:state_selected="true"
        android:state_window_focused="true"
    android:drawable="@drawable/list_highlight_inactive" />
    <item android:state_enabled="true" android:state_window_focused="true"
        android:drawable="@color/item_body" />
    <item android:drawable="@color/item_body" />
</selector>

Since I’m using SDK 1.5 I wasn’t able to use built-in Android styles so I had to copy list_highlight_active.xml and list_highlight_inactive.xml from /android-sdk-windows-1.6_r1/platforms/android-1.5/data/res/drawable to the drawable directory of my project. @color/item_body is just a shade of gray

Happy styling! Let me know if this worked for you