How do I close a SearchView programmatically?

AndroidSearchview

Android Problem Overview


I currently have a SearchView in the action bar of my app. When I click the search icon, the SearchView expands and the keyboard pops up as expected. Clicking the "X" in the SearchView box closes the SearchView as expected. However, when the SearchView is activated and I press the "back" button, my app is exited. This is the correct behavior, but what I am trying to do now is to capture back button press and just have it close the SearchView (not my app) when the SearchView is visible. Is there a way to invoke the SearchView OnCloseListener() programmatically on a back button press? For example, something like this:

// On a back button press, if we are currently searching,
// close the SearchView. Otherwise, invoke normal back button
// behavior.
public boolean onKeyDown(int keyCode, KeyEvent event) {
   if (keyCode == KeyEvent.KEYCODE_BACK) {
        if (isSearchViewVisible) {
	        SearchView searchView = (SearchView) menu.findItem(R.id.searchBox)
               .getActionView();

            // This method does not exist
            searchView.invokeClose();
        	return true;
        }
    }
    return super.onKeyDown(keyCode, event);
}

Android Solutions


Solution 1 - Android

Based on @MarcinOrlowski answer, also you can use:

@Override
public void onBackPressed() {
    if (!searchView.isIconified()) {
        searchView.setIconified(true);
    } else {
        super.onBackPressed();
    }
}

Solution 2 - Android

Use

searchView.setIconified(true)

I also used MenuItemCompat.collapseActionView

MenuItemCompat.collapseActionView(menuItem)

EDITED

> This method was deprecated in API level 26.1.0. Use collapseActionView() directly.

MenuItem#collapseActionView()

Solution 3 - Android

There is a simple way to do this:

@Override
public void onBackPressed() {
    if (!searchView.isIconified()) {
        searchView.onActionViewCollapsed();
    } else {
        super.onBackPressed();
    }
}

or use:

myToolBar.collapseActionView();

This will make the searchView to collapse before you press the back then the back action will be called.

Both solutions will work.

Solution 4 - Android

this is the only thing that does it for me:

  toolbar.collapseActionView();

Solution 5 - Android

To intercept BACK button override onBackPressed() (see docs)

@Override
public void onBackPressed() {

    if (isSearchViewVisible) {
        SearchView searchView = (SearchView) menu.findItem(R.id.searchBox)
           .getActionView();

        // This method does not exist
        searchView.invokeClose();
    } else {
        super.onBackPressed();
    }
}

EDIT:

Docs say:

> If necessary, you can expand or collapse the action view in your own > code by calling expandActionView() and collapseActionView() on the > MenuItem.

Solution 6 - Android

if you have input on your searchView

mSearchView.setIconified(true);

will only clear the text.

The correct method to close a searchView is

mSearchView.onActionViewCollapsed();

Solution 7 - Android

No need to use onBackPressed() method for this!! I found the solution, do only as I mentioned below so that the SearchView itself handle the on back button press event.

Inside your onCreateOptionsMenu() method,

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    MenuItem menuItem = menu.findItem(R.id.action_search);
    SearchView searchview = (SearchView) menuItem.getActionView();
    searchview.setIconifiedByDefault(true);
    searchview.setQueryHint("Enter your keyword");
    searchview.setOnQueryTextListener(this); 
    super.onCreateOptionsMenu(menu, inflater);
}

In your menu.xml add showAsAction attribute and set its values as "always|collapseActionView"

<item
    android:id="@+id/action_search_item"
    android:title="Search"
    android:icon="@drawable/ic_search_logo"
    app:showAsAction="always|collapseActionView"
    app:actionViewClass="android.support.v7.widget.SearchView"/>

And you're ready to go ;)

P.S. - I was searching for a solution from a long time and now I found one, hope it helps you all.

Solution 8 - Android

I prefer !searchView.isIconified() over if(isSearchViewVisible) inside the onBackPressed() method as option 2 does not work when you have fragments added in your fragmentmanager's backstack that you would like to show when the back button is pressed.

Solution 9 - Android

Use:

searchView.setIconified(true);

Solution 10 - Android

In Kotlin;

Firstly clear the typed text (optional)

searchView.isIconified = true

Second, close the searchview

searchView.onActionViewCollapsed()

Exstra, open searchview programatically

searchView.onActionViewExpanded()

Solution 11 - Android

My way:

  1. Create CustomSearchView class

public class CustomSearchView extends SearchView{
    public CustomSearchView(final Context context) {
        super(context);
        this.setIconifiedByDefault(true);
    }
    
    @Override
    public boolean dispatchKeyEventPreIme(KeyEvent event) {
        if (event.getKeyCode() == KeyEvent.KEYCODE_BACK && 
            event.getAction() == KeyEvent.ACTION_UP) {
            this.onActionViewCollapsed();
        }
        return super.dispatchKeyEventPreIme(event);
    }
}

  1. Add actionViewClass

<item
android:id="@+id/menu_search"
android:title="@string/menu_search"
android:icon="@drawable/ic_search"
android:showAsAction="collapseActionView|ifRoom"
android:actionViewClass="com.myapp.CustomSearchView"/>

  1. Create CustomSearchView into onCreateOptionsMenu
    CustomSearchView searchView = (CustomSearchView)menu.findItem(R.id.menu_search).getActionView();
    

Solution 12 - Android

If you are not use any function in onBackPressed() method ,remove it from your Activity.So that the SearchView itself handle the onBackPress event.

I am using SearchView as

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
	MenuItem searchItem = menu.findItem(R.id.action_search);
	SearchView searchview = (SearchView) MenuItemCompat.getActionView(searchItem);
	searchview.setIconifiedByDefault(true);
	searchview.setOnQueryTextListener(this);
	searchview.setSubmitButtonEnabled(true);  
	searchview.setQueryHint("Search Here"); 
	super.onCreateOptionsMenu(menu, inflater);
}

and my menu.xml as follows

<item
    android:id="@+id/action_search"
    android:icon="@drawable/search_tool"
    android:orderInCategory="1"
    android:title="Search" 
    app:actionViewClass="android.support.v7.widget.SearchView"
    app:showAsAction="always|collapseActionView"/>

Solution 13 - Android

Also you can use collapseActionView. It automatically handle back button, collapsing SearchView

<item
      android:id="@+id/action_search"
      android:icon="@drawable/ic_magnify"
      android:title="@string/action_title_search"
      app:actionViewClass="android.support.v7.widget.SearchView"
      app:showAsAction="ifRoom|collapseActionView" />

Solution 14 - Android

The following worked for me. I am trying to close search-view from Fragment in Jetpack NavigationView when a user clicks the back button -

requireActivity().getOnBackPressedDispatcher().addCallback(getViewLifecycleOwner(), new OnBackPressedCallback(true) { @Override public void handleOnBackPressed() {

        try {
            DashboardActivity activity = (DashboardActivity) getActivity();
            if (activity!=null) {
                if (!activity.mSearchView.isIconified()) {
                    activity.mSearchView.setQuery("",false);
                    activity.mSearchView.setIconified(true);
                } else {
                    NavController navController = Navigation.findNavController(activity, R.id.nav_host_fragment);
                    navController.popBackStack();
                }
            }

        }catch (Exception e){
            e.printStackTrace();
        }
    }
});

Solution 15 - Android

Most Worked Solution:

MenuItem menuItem = ....//
menuItem.collapseActionView();

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionTimView Question on Stackoverflow
Solution 1 - AndroidMohsen AfshinView Answer on Stackoverflow
Solution 2 - AndroidbetorcsView Answer on Stackoverflow
Solution 3 - AndroidbluewareView Answer on Stackoverflow
Solution 4 - AndroidraklosView Answer on Stackoverflow
Solution 5 - AndroidMarcin OrlowskiView Answer on Stackoverflow
Solution 6 - AndroidDoruChideanView Answer on Stackoverflow
Solution 7 - AndroidvishalsehgalView Answer on Stackoverflow
Solution 8 - AndroidCodedroidView Answer on Stackoverflow
Solution 9 - AndroidAlexView Answer on Stackoverflow
Solution 10 - AndroidAhmet B.View Answer on Stackoverflow
Solution 11 - AndroidSergei KView Answer on Stackoverflow
Solution 12 - AndroidSachinSView Answer on Stackoverflow
Solution 13 - AndroidDeni ErdyneevView Answer on Stackoverflow
Solution 14 - AndroidPramodView Answer on Stackoverflow
Solution 15 - AndroidRomanView Answer on Stackoverflow