11

Im using an action bar and adding a searchView to it. I have implemented the searchView.onCLoseListener but this does not seem to be getting invoked. Any suggestions ?

My code looks something like this :

SearchView searchView = new SearchView(getContext());
searchView.setOnCloseListener(new OnCloseListener() {

  public boolean onClose() {
    searchView.setVisibility(SearchView.GONE);
    // Do Something

    return true;
  }
});
lokoko
  • 5,785
  • 5
  • 35
  • 68

9 Answers9

43

I ran into same problem on android 4.1.1. Looks like it is a known bug: https://code.google.com/p/android/issues/detail?id=25758

Anyway, as a workaround i used state change listener (when SearchView is detached from action bar, it is also closed obviously).

view.addOnAttachStateChangeListener(new OnAttachStateChangeListener() {

    @Override
    public void onViewDetachedFromWindow(View arg0) {
        // search was detached/closed
    }

    @Override
    public void onViewAttachedToWindow(View arg0) {
        // search was opened
    }
});

Above code worked well in my case.

Dario
  • 2,053
  • 21
  • 31
  • Nice approach. Working – tornic Apr 25 '18 at 09:58
  • With this answer, you said "you are safe now my sweet child", and I am here to tell you: "I owe you my life". Legit, this answer works great. There are no sensible options controlling the SearchView status, and after a day of searching I found this and tried it - and it just. works. Four years after this was posted it's still extremely relevant. Should definitely be the accepted answer! – TomQDRS Dec 24 '18 at 16:19
  • I'd like to add, that it only worked for me, when I wrote ... (new View.OnAttachStateChangeListener() ... Took me awhile, I hope I can spare you the time – notADev May 28 '20 at 07:18
  • 1
    6 years on and this is still the best answer. Google is yet to fix this. – BVB09 Jul 29 '20 at 22:26
5

In order call onClose() method from SearchView.OnCloseListener. I made it working in the following way. Add this to your searchview

searchView.setIconifiedByDefault(true);
searchView.setOnCloseListener(this);

Now implement this onclick listener

  searchView.findViewById(R.id.search_close_btn)
                .setOnClickListener(new View.OnClickListener() {
                    @Override
                public void onClick(View v) {
                    Log.d("called","this is called.");
                    searchView.setQuery("",false);
                    searchView.setIconified(true);

                }
            });

This worked for me. Sharing so that it can help somebody else also. Thanks

Parmod
  • 51
  • 1
  • 2
3

To get notified when the 'x' icon is clicked, I added an on click listener to the SearchView 'x' button.

Find the SearchView 'x' button by id and attach the OnClickListener:

mSearchView.findViewById(R.id.search_close_btn)
    .setOnClickListener(this);

The view search_close_btn is present in the SearchView layout provided by the Android framework.

Charlie
  • 2,876
  • 19
  • 26
2

Ok. i got the mistake. We cant add a searchCommand and do

setShowAsAction(MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW)

Doing this would remove the searchText if any and hence we cant do a onClose().

lokoko
  • 5,785
  • 5
  • 35
  • 68
2
    MenuItemCompat.OnActionExpandListener expandListener = new MenuItemCompat.OnActionExpandListener() {
        @Override
        public boolean onMenuItemActionCollapse(MenuItem item) {
            // Do something when action item collapses
            /*Hiding the mic on search visibility*/
                myMenu.findItem(R.id.action_speak).setVisible(false);
            Log.v("test","colllapse");
            return true;  // Return true to collapse action view
        }

        @Override
        public boolean onMenuItemActionExpand(MenuItem item) {
            // Do something when expanded
            Log.v("test","expand");
            return true;  // Return true to expand action view
        }
    };

    //Searchview Initilisation
    MenuItem searchViewItem = menu.findItem(R.id.action_search);
    // Assign the listener to that action item
    MenuItemCompat.setOnActionExpandListener(searchViewItem, expandListener);

More info from here: https://developer.android.com/training/appbar/action-views.html

Raidri
  • 17,258
  • 9
  • 62
  • 65
Ajay S
  • 141
  • 1
  • 8
1

What I did to sort out a similar problem is I created a new class that extended SearchView:

public class EnglishVerbSearchView extends SearchView {

OnSearchViewCollapsedEventListener mSearchViewCollapsedEventListener;

public EnglishVerbSearchView(Context context) {
    super(context);
}

@Override
public void onActionViewCollapsed() {
    if (mSearchViewCollapsedEventListener != null)
        mSearchViewCollapsedEventListener.onSearchViewCollapsed();
    super.onActionViewCollapsed();
}

public interface OnSearchViewCollapsedEventListener{
    public void onSearchViewCollapsed();
}

public void setOnSearchViewCollapsedEventListener(OnSearchViewCollapsedEventListener eventListener) {
    mSearchViewCollapsedEventListener = eventListener;
}

}

You can then use this class instead of SearchView in your menu xml file:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:yourapp="http://schemas.android.com/apk/res-auto" >
    <item android:id="@+id/action_search"
      android:title="@string/action_search"
      android:icon="@drawable/action_search"
      yourapp:showAsAction="ifRoom|collapseActionView"
      yourapp:actionViewClass="com.szymontrapp.englishverbs.EnglishVerbSearchView" />
</menu>

And then you can add a listener in your activity:

    getMenuInflater().inflate(R.menu.dictionary, menu);
    MenuItem searchItem = menu.findItem(R.id.action_search);
    EnglishVerbSearchView searchView = (EnglishVerbSearchView)      MenuItemCompat.getActionView(searchItem);       

    // Get the SearchView and set the searchable configuration
    SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
    // Assumes current activity is the searchable activity
    searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
    searchView.setIconifiedByDefault(false); // Do not iconify the widget; expand it by default

    searchView.setOnSearchViewCollapsedEventListener(listener);

You can also override other methods in your class that replaces SearchView to achieve other goals.

Szymon
  • 42,577
  • 16
  • 96
  • 114
  • 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. Any thoughts or ideas on how to fix? – AJW Apr 30 '17 at 03:17
0

If you have set the

searchView.setIconifiedByDefault(false)

then, your searchView never closes as it is always in expanded mode. This is the reason why your onClose() is not being invoked.

0

Create the menu item with the app:showAsAction set to always.

<item   
 android:id="@+id/action_search"  
 android:title="..."  
 android:icon="..."  
 app:actionViewClass="android.support.v7.widget.SearchView"  
 app:showAsAction="always"/>

When creating the SearchView in the onCreateOptionsMenu method do something like this

inflater.inflate(R.menu.menu_search, menu);
final MenuItem item = menu.findItem(R.id.action_search);
final SearchView search = (SearchView) item.getActionView();
search.setQueryHint(getString(R.string.search_brand_item));
search.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
  @Override
  public boolean onQueryTextSubmit(String query) {
    // add your code
    return false;
  }

  @Override
  public boolean onQueryTextChange(String newText) {
    // add your code 
    return false;
  }
});
search.setOnCloseListener(new SearchView.OnCloseListener() {
  @Override
  public boolean onClose() {
    // add your code here
    return false;
  }
});
search.setIconifiedByDefault(true); // make sure to set this to true

The search.setIconifiedByDefault(true) needs to be set to true to call the onClose() method on the SearchView.OnCloseListener() created above.

Ray Hunter
  • 15,137
  • 5
  • 53
  • 51
0

I'm also find this problem. the solution is very simple! Just store your SearchView view in private var. Then use

  • isShown method to check if view was expanded,
  • searchview.addOnLayoutChange to determine searchview start using isShown after if block do your actions,
  • override onBackPressed with if block(searchView !=null && searchView.isShown() then do your actions when user click back button,
  • and override home(back) button listener in onOptionsItemSelected with isShown block. Note: in menu item xml file remove app:showAsAction collapseActionView flag.
Simon.S.A.
  • 6,240
  • 7
  • 22
  • 41
Nevidimka
  • 25
  • 4