Bartosz Bialecki
Bartosz Bialecki

Reputation: 4451

Android: SearchView setQuery does not set text on orientation change

I have SearchView which I want to programmatically expand and set text when the device orientation change. I tried many found solution but nothing work. If I use only setQuery then my list is filtered, but when I use also expandActionView then the search view does not contain the given search text and onQueryTextChange is called twice, first with the given text and the second time with the empty text.

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    menu.clear();
    inflater.inflate(R.menu.activity, menu);

    SearchManager searchManager = (SearchManager) getActivity().getSystemService(Context.SEARCH_SERVICE);
    MenuItem searchMenuItem = menu.findItem(R.id.search);
    SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchMenuItem);
    searchView.setIconifiedByDefault(true);
    searchView.setSearchableInfo(searchManager.getSearchableInfo(getActivity().getComponentName()));
    searchView.setOnQueryTextListener(this);

    MenuItemCompat.setOnActionExpandListener(searchMenuItem, new MenuItemCompat.OnActionExpandListener() {
        @Override
        public boolean onMenuItemActionCollapse(MenuItem item) {
            mCurrentQueryString = null;

            if (mAdapter != null) {
                mAdapter.clearFilter();
                mStopSearching = true;
            }

            return true;
        }

        @Override
        public boolean onMenuItemActionExpand(MenuItem item) {
            if (mAdapter != null) {
                mStopSearching = false;
            }

            return true;
        }
    });

    mSearchView = searchView;
    mSearchMenuItem = searchMenuItem;

    mSearchView.post(new Runnable() {
            @Override
            public void run() {
                MenuItemCompat.expandActionView(mSearchMenuItem);
                mSearchView.setQuery(mCurrentQueryString, true);
            }
        });

    super.onCreateOptionsMenu(menu, inflater);
}

I use the search view in the fragment which is used in the view pager. The fragment is retained. The problem is that onQueryTextChange function is called twice, by the second time with the empty text, but I am not sure why. This function is also called with the empty text when I first time open the search view when the fragment is initialized, but when close the serach view and open it again, this function is not called.

How can I fix it?

Upvotes: 2

Views: 1101

Answers (1)

azizbekian
azizbekian

Reputation: 62189

I've also faced that issue. The solution I've come up with was via posting with handler.

@Override public boolean onPrepareOptionsMenu(Menu menu) {
    ...
    // SearchView doesn't retain it's state after orientation change
    // have to handle it the bad way (╯°□°)╯︵ ┻━┻
    boolean isQueryExists = !TextUtils.isEmpty(mSearchQuery);

    if (isQueryExists) {
        // Calling directly doesn't take effect
        // Custom runnable class in order to refrain from context leakage
        new Handler(Looper.getMainLooper()).post(new SearchMenuRunnable(mSearchView, mSearchQuery));
    }

    ...
}

SearchMenuRunnable.java

public class SearchMenuRunnable implements Runnable {

private WeakReference<SearchView> mSearchViewWeakReference;
private String mSearchQuery;

public SearchMenuRunnable(SearchView searchView, String searchQuery) {
    mSearchViewWeakReference = new WeakReference<>(searchView);
    mSearchQuery = searchQuery;
}

@Override public void run() {
    if (null != mSearchViewWeakReference.get()) {
        SearchView searchView = mSearchViewWeakReference.get();
        searchView.setIconified(false);
        searchView.setQuery(mSearchQuery, true);
        searchView.clearFocus();
    }
}

This are source from one of projects in github. You can examine them here, it's pretty simple project.

Upvotes: 1

Related Questions