4

I'm trying to use the SearchView Support v4 version with action bar sherlock.

So i have my search button in the action bar -> when i touch it the keyboard show up and the searchBar too.

My problem is that i need to use the listeners onQueryTextSubmit and onQueryTextChange but they are never fired. I need to use the searh query string and do custom stuff with it.

Here is the full activity.java

public class ActivityMain extends SherlockFragmentActivity implements OnQueryTextListener, DialogFragmentListener {
    /**
     * PRIVATE ATTRIBUTES
     */
    private static final String TAG                             = "ActivityMain";
    private ViewPager           _viewPager;
    private TabsAdapter         _tabsAdapter;
    private DialogFiltre        _dialogFiltre;
    private String              _searchCurrentQuery;
    // data
    private boolean             _doubleBackToExitPressedOnce    = false;


    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {

        menu.clear();
        switch ((int) _viewPager.getCurrentItem()) {
            case 0:
                getSupportMenuInflater().inflate(R.menu.empty_menu, menu);
                break;
            case 1:
                getSupportMenuInflater().inflate(R.menu.action_bar_menu, menu);
                break;
            case 2:
                getSupportMenuInflater().inflate(R.menu.empty_menu, menu);
                break;
        }
        return super.onPrepareOptionsMenu(menu);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        getSupportMenuInflater().inflate(R.menu.action_bar_menu, menu);
        MenuItem searchItem = menu.findItem(R.id.search);
        SearchView searchView = (SearchView) searchItem.getActionView();
        searchView.setSubmitButtonEnabled(true);
        searchView.setOnQueryTextListener(queryTextListener);
        return true;
    }

    @Override
    public boolean onQueryTextSubmit(String query) {

        Log.i(TAG, "onQueryTextSubmit--");
        onSearchClicked(query);
        // hide keyboard
        InputMethodManager inputManager = (InputMethodManager) this.getSystemService(Context.INPUT_METHOD_SERVICE);
        inputManager.hideSoftInputFromWindow(this.getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
        return false;
    }

    @Override
    public boolean onQueryTextChange(String newText) {

        Log.d(TAG, "onQueryTextChange--");
        _searchCurrentQuery = newText.toString();
        EtablissementApplication._adapter.getFilter().filter(_searchCurrentQuery);
        return true;
    }

    private void onSearchClicked(String query) {

        Log.d(TAG, "onSearchClicked--");
        _searchCurrentQuery = query.toString();
        EtablissementApplication._adapter.getFilter().filter(_searchCurrentQuery);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        switch (item.getItemId()) {
            case android.R.id.home:
                getSupportActionBar().setDisplayHomeAsUpEnabled(false);
                break;
            case R.id.search:
                break;
            case R.id.menu_filtre:
                _dialogFiltre = DialogFiltre.newInstance(R.string.menu_filtre, this);
                _dialogFiltre.setValidDialogListener(this);
                _dialogFiltre.show(getSupportFragmentManager(), null);
                break;
        }
        return super.onOptionsItemSelected(item);
    }
An-droid
  • 6,433
  • 9
  • 48
  • 93

3 Answers3

11

You are trying to use a new SearchView instead of using the one created by the SupportMenuInflater. You setting the listener to different SearchView that you see on the screen. Also, every time onPrepareOptionsMenu is called, new SearchView is created, and thus it has no listeners set.

Try to do onPrepareOptionsMenu like this:

@Override
public boolean onPrepareOptionsMenu(Menu menu) {

    menu.clear();
    switch ((int) _viewPager.getCurrentItem()) {
        case 0:
            getSupportMenuInflater().inflate(R.menu.empty_menu, menu);
            break;
        case 1:
            getSupportMenuInflater().inflate(R.menu.action_bar_menu, menu);
            MenuItem searchItem = menu.findItem(R.id.search);
            SearchView searchView = (SearchView) searchItem.getActionView();
            searchView.setSubmitButtonEnabled(true);
            searchView.setOnQueryTextListener(queryTextListener);
            break;
        case 2:
            getSupportMenuInflater().inflate(R.menu.empty_menu, menu);
            break;
    }
    return super.onPrepareOptionsMenu(menu);
}

And remove the overridden method

@Override
public boolean onCreateOptionsMenu(Menu menu) { }
Yaroslav Mytkalyk
  • 16,950
  • 10
  • 72
  • 99
  • your suggestion good, i tried, but i still won't get my Log. Is there anything i need to set in the manifest or anywhere else that could block the listeners ? – An-droid May 31 '13 at 10:02
  • From the snippet you provided I do not see any other errors. Post the full Activity code with the imports and maybe we'll see something. – Yaroslav Mytkalyk May 31 '13 at 11:06
  • i have copied the whole activity, when the problem is solved i'll remove is from the post... – An-droid May 31 '13 at 12:03
  • you are a life saver, it works !! But i still dont understand why i only need onPrepareOptionsMenu(). I though that both methods where needed to setUp the menu correctly >. – An-droid May 31 '13 at 12:21
  • 1
    OnCreateOptionsMenu is called only once, but onPrepareOptionsMenu can be called every time the menu is invalidated. The menu.clear();, getSupportMenuInflater().inflate are called number of times after onCreateOptionsMenu and thus creating a new SearchView object with no listeners. – Yaroslav Mytkalyk May 31 '13 at 12:34
  • ahh i see, the problem comes with the menu.clear() that i call to update the menuItems. Thanks for the help. By the way, can i have your opinion. With Abs what is the best/easiest way to change menuItems according to the current tab ? – An-droid May 31 '13 at 12:41
  • @Yume117 put your menus in Fragments. http://stackoverflow.com/questions/8308695/android-options-menu-in-fragment – Yaroslav Mytkalyk May 31 '13 at 14:09
1

Top result in Google so adding a new possible cause that just gave me a headache. Be mindful of which SearchView implementation you reference.

This did not work for me (compiles, does not crash, but listener does not work):

    <!--actionbar.xml-->
    ...
    <item android:id="@+id/search"
        android:title="@string/action_search"
        android:icon="@drawable/ic_search"
        app:showAsAction="collapseActionView|ifRoom"
        app:actionViewClass="android.widget.SearchView"/>
    ...
    // Activity#onCreateOptionsMenu(android.view.Menu)
    val searchView: SearchView = menu.findItem(R.id.search).actionView as android.widget.SearchView
    searchView.setOnQueryTextListener(...)

This does (compiles, does not crash, and listener works):

    <!--actionbar.xml-->
    ...
    <item android:id="@+id/search"
        android:title="@string/action_search"
        android:icon="@drawable/ic_search"
        app:showAsAction="collapseActionView|ifRoom"
        app:actionViewClass="androidx.appcompat.widget.SearchView"/>
    ...
    // Activity#onCreateOptionsMenu(android.view.Menu)
    val searchView: SearchView = menu.findItem(R.id.search).actionView as androidx.appcompat.widget.SearchView
    searchView.setOnQueryTextListener(...)
Michael Jess
  • 1,907
  • 1
  • 19
  • 17
0

You may have to set searchView.setOnQueryTextListener(this); on your SearchView reference.

Haseeb Pavaratty
  • 554
  • 3
  • 17