Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using SearchView with AppCompatActivity results in UI glitches

I am trying to create an Android app with a search button in the Action Bar and when the user presses on the search button, then a search text box appears on the action bar, like in Google's Messenger app (see below). Google's Messenger with collapsed search action. Google's Messenger with expanded search action.

I tried to implement it as shown below but my app looks like this: My app with collapsed search action My app with expanded search action

There are a few problems with this. For example, the text reads "Search..." with the elipsis, unlike a simple "Search" without the elipsis, but by far the most concerning thing, is that there is no back button in the toolbar, the search button is pushed too far to the left, and the overflow button on the right has been pushed to the side. In addition, pressing the physical back button on my device does not collapse the searchview, it just exists to app.

Some of the code which I used to try to implement the search bar is below. I tried to set a SearchViewExpandListener as seen below so that the back button would appear when the search view is expanded, however it does not work.

EDIT: I also ran the app with breakpoints on my onMenuItemActionExpand and onMenuItemActionCollapsed methods, and I found out that these methods are in fact never called.

MainActivity.java

import android.content.Context;
import android.support.v4.view.MenuItemCompat;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.SearchView;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        getSupportActionBar().setDisplayShowHomeEnabled(false);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu, menu);

        MenuItem searchItem = menu.findItem(R.id.action_search);
        SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
        // See above
        MenuItemCompat.setOnActionExpandListener(searchItem, new SearchViewExpandListener(this));
        MenuItemCompat.setActionView(searchItem, searchView);

        searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {

            @Override
            public boolean onQueryTextSubmit(String s) {
                Toast.makeText(MainActivity.this, "You searched " + s, Toast.LENGTH_SHORT).show();
                return false;
            }

            @Override
            public boolean onQueryTextChange(String s) {
                return false;
            }
        });
        return true;
    }

// See above
    private class SearchViewExpandListener implements MenuItemCompat.OnActionExpandListener {

        private Context context;

        public SearchViewExpandListener (Context c) {
            context = c;
        }

        @Override
        public boolean onMenuItemActionExpand(MenuItem item) {
            ((AppCompatActivity) context).getSupportActionBar().setDisplayShowHomeEnabled(true);
            return false;
        }

        @Override
        public boolean onMenuItemActionCollapse(MenuItem item) {
            ((AppCompatActivity) context).getSupportActionBar().setDisplayShowHomeEnabled(false);
            return false;
        }
    }
}

menu.xml

<?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_search"
        android:title="Search"
        app:actionViewClass="android.support.v7.widget.SearchView"
        app:showAsAction="ifRoom"/>

    <item android:id="@+id/action_about"
        android:title="About"
        app:showAsAction="never"/>
</menu>

It also appears that it is not just me who has this problem. This guide on implementing a SearchView appears to experience similar issues.

This guy's problem which is like mine.

So what is the correct way to implement a search bar in an AppCompatActivity which results in a search bar like that in Google's Material Design guidelines and like that in their apps such as Google Messenger? I feel like I've been Googling endlessly for the past while, but I cannot find anything which helps me.

like image 350
Bentley Carr Avatar asked Jan 04 '16 18:01

Bentley Carr


People also ask

How to add SearchView in Android Studio?

To add a SearchView widget to the app bar, create a file named res/menu/options_menu. xml in your project and add the following code to the file. This code defines how to create the search item, such as the icon to use and the title of the item.


1 Answers

Use collapseActionView flag along with always in showAsAction on serchView menu item

app:showAsAction="always|collapseActionView"

The collapseActionView flag indicates how to display the widget when the user is not interacting with it: If the widget is on the app bar, the app should display the widget as an icon. If the widget is in the overflow menu, the app should display the widget as a menu item. When the user interacts with the action view, it expands to fill the app bar.

like image 93
Bhargav Thanki Avatar answered Oct 03 '22 02:10

Bhargav Thanki