Styling the SearchView with AppCompat v21 (material theme)

Earlier versions of the AppCompat-v7 library conveniently exposed a huge number of styling attributes that were hidden in the standard holo themes. A number of these attributes allowed customisation of the SearchView widget on the ActionBar.

I'll quickly summarise the way to style the SearchView with AppCompat v20 for completeness, then discuss the differences with v21.

The old way

In v20 there are a number of attributes defined which apply to the SearchView widget:

<attr name="searchResultListItemHeight" format="dimension" />
<attr name="searchViewAutoCompleteTextView" format="reference" />
<attr name="searchViewCloseIcon" format="reference" />
<attr name="searchViewEditQuery" format="reference" />
<attr name="searchViewEditQueryBackground" format="reference" />
<attr name="searchViewGoIcon" format="reference" />
<attr name="searchViewSearchIcon" format="reference" />
<attr name="searchViewTextField" format="reference" />
<attr name="searchViewTextFieldRight" format="reference" />
<attr name="searchViewVoiceIcon" format="reference" />

These are defined within the various AppCompat themes, including Theme.AppCompat, Theme.AppCompat.Light and Theme.AppCompat.Light.DarkActionBar.

You can customise the SearchView styles in your theme as follows:

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="actionBarWidgetTheme">@style/AppTheme.WidgetTheme</item>
</style>

<style name="AppTheme.WidgetTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="searchViewSearchIcon">@drawable/ic_action_search</item>
    <item name="searchViewCloseIcon">@drawable/ic_action_close</item>
</style>

The new way

In v21 the attributes have been re-organised and found their way into the declare-styleable section for SearchView:

<declare-styleable name="SearchView">
    <!-- The layout to use for the search view. -->
    <attr name="layout" format="reference" />
    <!--
         The default state of the SearchView. If true, it will be iconified when not in
         use and expanded when clicked.
    -->
    <attr name="iconifiedByDefault" format="boolean" />
    <!-- An optional maximum width of the SearchView. -->
    <attr name="android:maxWidth" />
    <!-- An optional query hint string to be displayed in the empty query field. -->
    <attr name="queryHint" format="string" />
    <!-- The IME options to set on the query text field. -->
    <attr name="android:imeOptions" />
    <!-- The input type to set on the query text field. -->
    <attr name="android:inputType" />
    <!-- Close button icon -->
    <attr name="closeIcon" format="reference" />
    <!-- Go button icon -->
    <attr name="goIcon" format="reference" />
    <!-- Search icon -->
    <attr name="searchIcon" format="reference" />
    <!-- Voice button icon -->
    <attr name="voiceIcon" format="reference" />
    <!-- Commit icon shown in the query suggestion row -->
    <attr name="commitIcon" format="reference" />
    <!-- Layout for query suggestion rows -->
    <attr name="suggestionRowLayout" format="reference" />
    <!-- Background for the section containing the search query -->
    <attr name="queryBackground" format="reference" />
    <!-- Background for the section containing the action (e.g. voice search) -->
    <attr name="submitBackground" format="reference" />
    <attr name="android:focusable" />
</declare-styleable>

Theme has also gained a new styleable attribute specifically for the SearchView:

<!-- Style for the search query widget. -->
<attr name="searchViewStyle" format="reference" />

There are some new styles defined specifically for the SearchView such as Widget.AppCompat.SearchView and Widget.AppCompat.Light.SearchView.

So, to implement the v20 example above in v21 we would end up with something like this:

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="searchViewStyle">@style/AppTheme.SearchView</item>
</style>

<style name="AppTheme.SearchView" parent="Widget.AppCompat.SearchView">
    <item name="searchIcon">@drawable/ic_action_search</item>
    <item name="closeIcon">@drawable/ic_action_close</item>
</style>

Final thoughts

Theming in Android has not always been the easiest thing to do and it looks like things have been greatly improved with Lollipop. The simplicity of the material theme is a huge time saver and it's good to see that this extends down into common use widgets too. The new SearchView attributes and themes are a much more logical and organised approach than we've had in the previous versions.