Emulating the Android People application’s ListView style

As of Android Ice Cream Sandwich (4.0.x), the default contacts application sports a fantastic new look. It’s both fast and appealing. One of the more interesting aspects of the application is the design of the main contacts list.

The ListView eschews the typical full-width layout in lieu of a padded layout with white margins on either side. These gutters allow for a persistent fast-scroll bar. Because of the extra white space provided by the gutters, the persistent scroll bar does not obscure the most important information, your contacts. It also provides a convenient way to quickly scrub through a long list of people (most of whom you never talk to anymore).

It was not immediately clear to me how they accomplished this layout. I was still puzzled even after reading through the source of the Contacts application.

Finally, after a great deal of thought and experimentation, I believe I’ve stumbled on the solution, and it’s really quite elegant.

Essentially, the key is the view’s setScrollBarStyle(int style) method. The default style appears to be SCROLLBARS_INSIDE_OVERLAY, which overlays the scroll bar on top of your list items without affecting the layout. This means that adding padding to the list view element will nudge the scroll bar in with the rest of your list content.

However, changing the scroll bar style to SCROLLBARS_OUTSIDE_OVERLAY places the scroll bar at the edge of the ListView, outside of your padding! This means that you can easily add padding to the list view element itself and the scroll bar will stay exactly where you want it.

In practice this can be done with very little effort:

    /** Style the <code>ListView</code> with a persistent scroll bar. */
    @TargetApi(11)
    private void setPersistentScrollBar() {
        ListView lv = getListView();
        lv.setFastScrollEnabled(true);
        lv.setFastScrollAlwaysVisible(true);
        lv.setScrollBarStyle(View.SCROLLBARS_OUTSIDE_OVERLAY);
 
        Resources r = getResources();
        int leftPadding = r.getDimensionPixelSize(
                R.dimen.list_view_padding_left);
        int rightPadding = r.getDimensionPixelSize(
                R.dimen.list_view_padding_right);
 
        // Add left and right padding to the ListView to accommodate the
        // persistent scroll bar.
        lv.setPadding(leftPadding, 0, rightPadding, 0);
    }

Dropping the setPersistentScrollBar() method into your ListActivity or ListFragment and invoking it in your onCreate(Bundle savedInstanceState) or onActivityCreated(Bundle savedInstanceState) (respectively) method should prove sufficient.

The only slightly tricky part is correctly padding the list view. In the example above, we’re specifying the padding in our code. However, you could easily do the same in your XML layout. For the example above to work properly, you’ll need to create a dimens.xml resource in your project’s res/xml directory that contains the following XML:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <dimen name="list_view_padding_left">16dp</dimen>
    <dimen name="list_view_padding_right">32dp</dimen>
</resources>

Finally, if you’re wondering how the pinned list headers work in the Contacts application, you should look over the PinnedHeaderListDemoActivity.java example in the Contact application source.

Happy coding!

2 thoughts on “Emulating the Android People application’s ListView style

  1. the pinned headers isn’t working for me, it doesnt have the same style
    can you help

Comments are closed.