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);
}
Based on @MarcinOrlowski answer, also you can use:
@Override
public void onBackPressed() {
if (!searchView.isIconified()) {
searchView.setIconified(true);
} else {
super.onBackPressed();
}
}
Use
searchView.setIconified(true)
I also used MenuItemCompat.collapseActionView
MenuItemCompat.collapseActionView(menuItem)
There is a simple way to do this:
@Override
public void onBackPressed() {
if (!searchView.isIconified()) {
searchView.onActionViewCollapsed();
} else {
super.onBackPressed();
}
}
or use:
@Override
public void onBackPressed() {
searchView.onActionViewCollapsed();
super.onBackPressed();
}
This will make the searchView to collapse before you press the back then the back action will be called.
Both solutions will work.
this is the only thing that does it for me:
toolbar.collapseActionView();
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:
If necessary, you can expand or collapse the action view in your own code by calling expandActionView() and collapseActionView() on the MenuItem.
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();
Use:
searchView.setIconified(true);
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.
My way:
- 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); } }
- 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"/>
- Create CustomSearchView into onCreateOptionsMenu
CustomSearchView searchView = (CustomSearchView)menu.findItem(R.id.menu_search).getActionView();
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"/>
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" />
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.
来源:https://stackoverflow.com/questions/17506230/how-do-i-close-a-searchview-programmatically