How can I capture the event of user click on clear SearchView
text by clicking on the X button on the right
I already captured onQueryTextChange
event but, this is for any text change not for that X button
How can I capture the event of user click on clear SearchView
text by clicking on the X button on the right
I already captured onQueryTextChange
event but, this is for any text change not for that X button
After trying a lot of combinations, I found how to capture the event behind the X button in SearchView
Below is a code snippet from onCreateOptionsMenu
function in one of my apps. mSearchMenu
and mSearchView
are global variables.
The X is actually an ImageView with ID search_close_btn
and the text area is an EditText view with ID search_src_text
@SuppressLint("NewApi")
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu items for use in the action bar
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.country_list_activity_actions, menu);
mSearchMenu = menu.findItem(R.id.action_search);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
// Get the SearchView and set the searchable configuration
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
mSearchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
// Assumes current activity is the searchable activity
mSearchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
mSearchView.setIconifiedByDefault(false); // Do not iconify the widget; expand it by default
// Get the search close button image view
ImageView closeButton = (ImageView)mSearchView.findViewById(R.id.search_close_btn);
// Set on click listener
closeButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
LoggerUtils.d(LOG, "Search close button clicked");
//Find EditText view
EditText et = (EditText) findViewById(R.id.search_src_text);
//Clear the text from EditText view
et.setText("");
//Clear query
mSearchView.setQuery("", false);
//Collapse the action view
mSearchView.onActionViewCollapsed();
//Collapse the search widget
mSearchMenu.collapseActionView();
}
});
}
// When using the support library, the setOnActionExpandListener() method is
// static and accepts the MenuItem object as an argument
mSearchMenu.setOnActionExpandListener(new OnActionExpandListener() {
@Override
public boolean onMenuItemActionExpand(MenuItem item) {
//Nothing to do here
LoggerUtils.d(LOG, "Search widget expand ");
return true; // Return true to expand action view
}
@Override
public boolean onMenuItemActionCollapse(MenuItem item) {
LoggerUtils.d(LOG, "Search widget colapsed ");
return true; // Return true to collapse action view
}
});
return super.onCreateOptionsMenu(menu);
}
you can just use the onCloseListener()
sv= (SearchView) findViewById(R.id.searchView1);
sv.setOnCloseListener(new OnCloseListener() {
@Override
public boolean onClose() {
Toast t = Toast.makeText(MainActivity.this, "close", Toast.LENGTH_SHORT);
t.show();
return false;
}
});
I had problems trying to find the component by its ID but I found another way to search this component using the context of the same SearchView
// Catch event on [x] button inside search view
int searchCloseButtonId = searchView.getContext().getResources()
.getIdentifier("android:id/search_close_btn", null, null);
ImageView closeButton = (ImageView) this.searchView.findViewById(searchCloseButtonId);
// Set on click listener
closeButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Manage this event.
}
});
I use this code to catch text query clearing, and perform my actions
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.search, menu);
SearchView searchView = (SearchView) menu.findItem(R.id.search_button).getActionView();
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
SearchView.OnQueryTextListener textChangeListener = new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextChange(String cs) {
if (TextUtils.isEmpty(cs)){
//Text is cleared, do your thing
}
return false;
}
@Override
public boolean onQueryTextSubmit(String query) {
//text query submitted
}
};
searchView.setOnQueryTextListener(textChangeListener);
return true;
}
If you use Appcompat library, instead of using
getResources().getIdentifier("android:id/search_close_btn", null, null);
you can do this:
MenuItem searchItem = menu.findItem(R.id.action_search);
SearchView searchView = (SearchView) searchItem.getActionView();
View closeButton = searchView.findViewById(android.support.v7.appcompat.R.id.search_close_btn);
closeButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//handle click
}
});
EDIT AUGUST 2019:
If you use androidx: androidx.appcompat.R.id.search_close_btn
If you are using the SearchView from androidx, you can do this:
val closeButton: View? = searchView.findViewById(androidx.appcompat.R.id.search_close_btn)
closeButton?.setOnClickListener {
//TODO: Set your action
}
The solution from Eduardo doesnt work for me. I found something else which is working for Kotlin. I found this solution thanks to SjoerdvGestel and it's answer.
// Get the close button on the searchView
val closeButtonId: Int = searching.context.resources.getIdentifier("android:id/search_close_btn", null, null)
val closeButton = searching.findViewById(closeButtonId) as ImageView
// On close collapse the searchView
closeButton.setOnClickListener {
searching.onActionViewCollapsed()
true
}
ImageView closeButton = (ImageView) this.searchView.findViewById(android.support.v7.appcompat.R.id.search_close_btn);
closeButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Manage this event.
}
});
Use R.id.search_go_btn for "Submit" Button
A kotlin answer:
mySearchView.setOnCloseListener(object : SearchView.OnCloseListener {
override fun onClose(): Boolean {
// Do your stuff
return false
}
})
To return to the initial state of the SearchView, you can make a clear focus when the "X" is pressed, in addition, this clear focus hides the keyboard.
searchview.setOnCloseListener(new SearchView.OnCloseListener() {
@Override
public boolean onClose() {
searchview.clearFocus();
return false;
}
});
I got this answer by checking the androidx.appcompat.widget.SearchView
class and checked for the id close button and found ImageView mCloseButton = findViewById(R.id.search_close_btn);
So the solution is to get the reference of this id in your searchView implementation and attach onClickListener to it. So what internally happens is that we are overriding the imageView's setOnClickListener and adding our implementation. Here is the code.
SearchView searchView = findViewById(R.id.search_view);
ImageView closeButton = searchView.findViewById(R.id.search_close_btn);
if (closeButton != null) closeButton.setOnClickListener(v -> {
//your logic goes in here
});
This is the code that worked for me:
ImageView closeButton = (ImageView) this.searchView.findViewById(androidx.appcompat.R.id.search_close_btn);
closeButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//DO SMTH
}
});
A kotlin clean & simple answer using (Lambda):
mySearchView.setOnCloseListener {
// Do your stuff
return false
}