Search code examples
androidsearchviewandroid-toolbar

Android appcompat toolbar stretches when searchview gets focus


I'm updating an app to use the new Toolbar instead of the regular ActionBar. In my app the user must be able to select a contact from their contact list. To do so, I've added a SearchView to the menu. The contacts are already in the list; the SearchView is used to filter the list using the ArrayAdapter.getFilter() method.

It all worked fine using the ActionBar, but the Toolbar's height gets stretched to just behind the keyboard. Using the XML inspection from Android Device Monitor I can see the ListView exists behind my keyboard.

It almost seems as if the SearchView wants to display suggestions, but I have no such thing configured. Any idea what's going wrong?

The images illustrate the problem. They show the normal, expanded and focused state of the SearchView.

This is my XML menu:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item android:id="@+id/action_forwarding_contact_search"
        app:showAsAction="always"
        android:title="@string/forwarding_contact_search"
        app:actionViewClass="android.support.v7.widget.SearchView"
        android:icon="@drawable/abc_ic_search_api_mtrl_alpha"/>
</menu>

Edit Giving the Toolbar a fixed height doesn't solve the problem, because it will make SearchView disappear when it has focus. Changing the gravity of either item seems to have no effect on the SearchView.

Normal state Expanded state Focused state


Solution

  • Ok, I figured it out. There was no problem with the SearchView, because the same happened with ordinary EditTexts which were placed normally inside a layout xml. The Toolbar wasn't the problem either.

    I created an empty activity and played around with anything I changed in my app and finally came to my theme. On KitKat and later I had <item name="android:windowTranslucentStatus">true</item> set on the theme, so the navigation drawer would appear behind the status bar.

    Disabling/removing this would resolve the issue. This reminded me of the android:fitsSystemWindows="true" property. It is set on the Toolbar, but not in the layout xml of the main activity that contains the DrawerLayout. I guess the DrawerLayout sets itself to fit the system windows. E.g. there's no fitSystemWindows property here:

    <android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/drawer_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".DashboardActivity">
    

    The activity where the problem occurred did not have a NavigationDrawer, it was a new activity. Setting android:fitsSystemWindows="true" on the root node of the layout of the activity made things work fine.

    So, for anyone to read this: if you have <item name="android:windowTranslucentStatus">true</item> in your theme, make sure any root node containing a toolbar contains a android:fitsSystemWindows="true".

    Working sample:

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true"
        android:orientation="vertical">
    
        <include layout="@layout/toolbar" />
    
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:orientation="vertical">
    
                <EditText
                    android:id="@+id/editText"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:singleLine="true" />
    
                <Button
                    android:id="@+id/button2"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="New Button" />
            </LinearLayout>
    </LinearLayout>