16

I have an actionbar with a search icon. When the search icon is clicked, it expands to a search bar in which the user can type in a search.

The problem is when the user enters the search I would like the search bar to collapse back to an icon but I can not get it to happen for the life of me.

My actionbar menu looks like this:

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context=".MainActivity" >

    <item android:id="@+id/menu_search2"
        android:actionViewClass="android.widget.SearchView"
        android:title="Search"
        android:icon="@android:drawable/ic_menu_search"
        android:showAsAction="always|collapseActionView|"
        android:onClick="goToSearch"
        />

    <item android:id="@+id/action_scan"
        android:icon="@drawable/barcode"
        android:onClick="scanBarcode"
        android:showAsAction="ifRoom|collapseActionView"
        />

</menu>

My search activity looks like this:

public class Search extends Fragment implements SearchView.OnQueryTextListener, ReadJSONResult.OnArticleSelectedListener {

    private ListView lv;
    View v;
    SearchView searchView;
    private SearchView mSearchView;
    private MenuItem mSearchMenuItem;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        //set layout here
        v = inflater.inflate(R.layout.activity_search, container, false);
        setHasOptionsMenu(true);
        getActivity().setTitle("Search");


        //get user information
        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
        String userName = prefs.getString("userName", null);
        String userID = prefs.getString("userID", null);


        return v;


}

    @Override
    public void onCreateOptionsMenu (Menu menu, MenuInflater inflater) {
        // Inflate the menu; this adds items to the action bar if it is present.

        searchView = (SearchView) menu.findItem(R.id.menu_search2).getActionView();
        searchView.setOnQueryTextListener(this);
        searchView.setIconified(false);
    }


    public boolean onQueryTextSubmit (String query) {

        //toast query
        //make json variables to fill
        searchView.setIconified(true);
        searchView.clearFocus();

        // url to make request
        String url = "myURL";



        try {
            query = URLEncoder.encode(query, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }


        String jsonUrl = url + query;


        //todo: get json
        ReadJSONResult task = new ReadJSONResult(getActivity());
        task.setOnArticleSelectedListener(this);
        task.execute(jsonUrl);

        return false;
    }





    @Override
    public boolean onQueryTextChange(String newText) {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public void onArticleSelected(String b, String brewery){
        searchView.setIconified(true);
        searchView.clearFocus();
        searchView.postInvalidate();
        //code to execute on click
        Fragment Fragment_one;
        FragmentManager man= getFragmentManager();
        FragmentTransaction tran = man.beginTransaction();

        //adds beer data to shared prefs for beer tabs
        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
        SharedPreferences.Editor editor = preferences.edit();
        editor.putString("beerID",b);
        editor.putString("breweryID",brewery);
        editor.commit();
        Fragment_one = new BeerTabs();

        tran.replace(R.id.main, Fragment_one);//tran.
        tran.addToBackStack(null);
        tran.commit();

    }



}
Mike
  • 6,301
  • 23
  • 70
  • 124

2 Answers2

34

One simpler way, that works even if the SearchView widget is not on the actionbar is the following code:

searchView.setQuery("", false);
searchView.setIconified(true);

And that makes the SearchView collapse after a search is made.

Nick
  • 936
  • 1
  • 10
  • 20
14

After some searches, I find the solution. The onActionViewCollapsed works but you had an unexpected behaviour (icon jumps to left, up indicator still here...) - this (hard) solution was suggested in my first and previous answer, and I was persuaded by use of collapseActionView method. However, SearchView.collapseActionView() was not working because according to the Documentation:

Collapse the action view associated with this menu item.

It's related to the MenuItem and not to the SearchView widget. That's why you had this error when you used this method:

The method collapseActionView() is undefined for the type SearchView

Then, the solution is to create a Menu variable as follows:

 // At the top of your class
 private Menu mMenu;

 // onCreateOptionsMenu method
 @Override
 public boolean onCreateOptionsMenu(Menu menu) {
      this.mMenu = menu; // init the variable
      // other stuff..
      return true;
 }

 // call the collapseActionView method
 public boolean onQueryTextSubmit(String query) {
      searchView.setIconified(true);
      searchView.clearFocus();
      // call your request, do some stuff..

      // collapse the action view
      if (mMenu != null) { 
          (mMenu.findItem(R.id.menu_search2)).collapseActionView();
      }
      return false;
 }

Or another might be to avoid the implement SearchView.OnQueryTextListener and to do it inside onCreateOptionsMenu as follows:

@Override
// make your Menu as 'final' variable
public void onCreateOptionsMenu (final Menu menu, MenuInflater inflater) {
    searchView = (SearchView) menu.findItem(R.id.menu_search2).getActionView();
    // call the query listener directly on the SearchView
    searchView.setOnQueryTextListener(new OnQueryTextListener() {
        @Override
        public boolean onQueryTextSubmit(String query) {
            searchView.setIconified(true);
            searchView.clearFocus();

            // call the request here

            // call collapse action view on 'MenuItem'
            (menu.findItem(R.id.menu_search2)).collapseActionView();

            return false;
        }
        @Override
        public boolean onQueryTextChange(String newText) { return false; }
    });
    searchView.setIconified(false);
}  

This will resolve the issue for sure. Happy coding!

fllo
  • 11,595
  • 5
  • 39
  • 95
  • So that almost worked perfectly, it collapsed like it should but didnt execute my search... My code looks like this now: https://gist.github.com/anonymous/cf26b36c5a22b64459b6 – Mike Apr 17 '14 at 22:12
  • It's because you have the query listener twice. Make sure you deleted the implement OnQueryListener and copy/paste all your stuff (json request, etc) **inside the same query listener** where you're collapse the view. Inside the code above which provide you a query listener. Do you see @Mike? – fllo Apr 17 '14 at 22:21
  • See my updated answer above. Call your request inside the listener at the commented line *"call your request here"*. HTH @Mike – fllo Apr 17 '14 at 23:23
  • Just tried that, but it does not like the this on this line: task.setOnArticleSelectedListener(this); – Mike Apr 17 '14 at 23:53
  • @Mike Try to attach the context instead: `task.setOnArticleSelectedListener(getActivity())` – fllo Apr 18 '14 at 00:06
  • nope I get this: setOnArticleSelectedListener (com.beerportfolio.beerportfoliopro.ReadJSONResult.OnArticleSelectedListener) in ReadJSONResult cannot be applied to (android.support.v4.app.FragmentActivity) – Mike Apr 18 '14 at 00:07
  • @Mike, Ahh, yes, you have two parameters on the declaration of onArticleSelected method. I thought about your json request indeed, no? – fllo Apr 18 '14 at 00:08
  • I am a little confused cause it looks like my old code had this in it and worked... – Mike Apr 18 '14 at 00:13
  • @Mike come into the chat please, I'll explain: let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/50928/discussion-between-fllo-and-mike) – fllo Apr 18 '14 at 00:16
  • 1
    Thanks .. You save my day. Above code worked perfectly. – Anil Chahal Jun 20 '16 at 07:45