87

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

Sufian
  • 6,405
  • 16
  • 66
  • 120
asmgx
  • 7,328
  • 15
  • 82
  • 143
  • I am also looking for an answer to this question. Anyone has a link because I searched for the past few hours on google and I couldn't find anything. – Sitram Jul 19 '14 at 09:50

13 Answers13

118

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);
    }
Sitram
  • 1,432
  • 1
  • 14
  • 17
  • I have a similar problem here: http://stackoverflow.com/questions/43702055/android-how-do-i-get-searchview-close-button-to-return-to-search-edittext?noredirect=1#comment74449117_43702055. mSearchView.onActionViewExpanded() doesn't work. Do you have any thoughts or ideas on how I can fix? – AJW Apr 30 '17 at 02:25
  • Very helpful. Thanks. – Pooja Oct 09 '19 at 15:11
58

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;
            }
        });
spaceMonkey
  • 4,475
  • 4
  • 26
  • 34
36

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.
    }
});
Jared Burrows
  • 54,294
  • 25
  • 151
  • 185
Jhegs
  • 497
  • 5
  • 8
29

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;
    }
Rafael
  • 6,091
  • 5
  • 54
  • 79
25

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

leon
  • 942
  • 11
  • 15
12

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
}
GianMS
  • 923
  • 2
  • 13
  • 25
  • 4
    A caveat on this is that it overrides the clear functionality. Then, you should call `searchView.setQuery("", false)` as well. – djserva Feb 18 '21 at 11:25
6

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
}
yanis labrak
  • 81
  • 2
  • 3
5
    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

VINAY DANARADDI
  • 195
  • 2
  • 12
5

A kotlin answer:

mySearchView.setOnCloseListener(object : SearchView.OnCloseListener {
            override fun onClose(): Boolean {
                // Do your stuff
                return false
            }
        })
Eduardo Viana
  • 51
  • 1
  • 2
2

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

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

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

A kotlin clean & simple answer using (Lambda):

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