How do I capture SearchView's clear button click?

AndroidSearchview

Android Problem Overview


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

Android Solutions


Solution 1 - Android

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);
	}

Solution 2 - Android

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;
	        }
	    });

Solution 3 - Android

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.
    }
});

Solution 4 - Android

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;
    }

Solution 5 - Android

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

Solution 6 - Android

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
}

Solution 7 - Android

    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

Solution 8 - Android

A kotlin answer:

mySearchView.setOnCloseListener(object : SearchView.OnCloseListener {
            override fun onClose(): Boolean {
                // Do your stuff
                return false
            }
        })

Solution 9 - Android

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
}

Solution 10 - Android

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;
            }
});

Solution 11 - Android

A kotlin clean & simple answer using (Lambda):

mySearchView.setOnCloseListener {
    // Do your stuff
    return false
}

Solution 12 - Android

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
    });

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
QuestionasmgxView Question on Stackoverflow
Solution 1 - AndroidSitramView Answer on Stackoverflow
Solution 2 - AndroidspaceMonkeyView Answer on Stackoverflow
Solution 3 - AndroidJhegsView Answer on Stackoverflow
Solution 4 - AndroidRafaelView Answer on Stackoverflow
Solution 5 - AndroidleonView Answer on Stackoverflow
Solution 6 - AndroidGianMSView Answer on Stackoverflow
Solution 7 - AndroidVINAY DANARADDIView Answer on Stackoverflow
Solution 8 - AndroidEduardo VianaView Answer on Stackoverflow
Solution 9 - Androidyanis labrakView Answer on Stackoverflow
Solution 10 - AndroidLautaro Villarreal Culic'View Answer on Stackoverflow
Solution 11 - AndroidDharamveer Mithilesh GuptaView Answer on Stackoverflow
Solution 12 - AndroidMohamed FarithView Answer on Stackoverflow