4

I've recently added a SearchView to my application (The one provided in support-v7 library). In my case the submit button should never start a new Intent with ACTION_SEARCH, I just want to show a list of suggestions that the user can browse and clicking one of them triggers some action.

I think that everything is correctly set up, but I've two big problems:

  • The first time I type something, even if all the events are triggered (I used some log prints to check this), the suggestions list doesn't show up, I have to clear the search text and restart writing, then the suggestions are shown. This happens only the very first time that I search something. If I close and re-open the SearchView, it shows suggestions since the first attempt.
  • To load suggestions, I query the ContentProvider through the LoaderManager, and if I type too quickly the app crashes saying that I'm trying to re-open an already-closed object (I guess the Cursor that I get by querying the ContentProvider).

What should I change in my code to make it work properly?

Code:

in onCreateOptionsMenu:

mActivity.getMenuInflater().inflate(R.menu.itemselect_search, menu);
SearchManager searchManager = (SearchManager) mActivity
        .getSystemService(Context.SEARCH_SERVICE);
searchView = (SearchView) menu.findItem(R.id.item_search)
        .getActionView();
searchView.setSearchableInfo(searchManager.getSearchableInfo(mActivity
        .getComponentName()));
searchView.setOnQueryTextListener(this);
searchView.setOnSuggestionListener(this);

my onQueryTextListener:

public boolean onQueryTextSubmit(String query) {
    return true;
}
public boolean onQueryTextChange(String newText) {
    Log.i("TextChange", "=(" + newText + ")");
    if (newText == null || newText.isEmpty()) {
        //Empty the suggestions instead of showing all items...
        if (null != mSuggestionAdapter)
            mSuggestionAdapter.swapCursor(null);
    } else {
        currentSearchQuery = newText;
        mActivity.getSupportLoaderManager().restartLoader(1, null, this);
    }
    return true;
}

my onCreateLoader:

public Loader<Cursor> onCreateLoader(int id, Bundle arg1) {
    CursorLoader mCursorLoader = null;
    switch (id) {
    //Other Loader IDs...
    case 1:
        Log.i("OnCreateLoader", "Loader created: " + id);
        mCursorLoader = new CursorLoader(mActivity,
                MyContentProvider.URI,
                SQLiteRomDataSource.allColumns,
                mSelection,
                mSelectionArgs, null);
        break;
    }
    return mCursorLoader;
}

my onLoadFinished:

public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
    switch (loader.getId()) {
    //Other Loader IDs...
    case 1:
        Log.i("OnLoadFinished",
                "Loader " + loader.getId() + ", " + cursor.getCount()
                        + " results");
        if (null == mSuggestionAdapter) {
            Log.i("OnLoadFinished","Creating adapter");
            mSuggestionAdapter = new SuggestionsCursorAdapter(
                    mActivity, cursor, 0);
        }
        if (searchView.getSuggestionsAdapter() != mSuggestionAdapter){
            Log.i("OnLoadFinished","Binding adapter to searchview");
            searchView.setSuggestionsAdapter(mSuggestionAdapter);
        }
        mSuggestionAdapter.swapCursor(cursor);
        Log.i("OnLoadFinished","Swapping cursor...");
        break;
    }
}

And finally my onLoaderReset:

@Override
public void onLoaderReset(Loader<Cursor> loader) {
    switch (loader.getId()) {
    //Other Loader IDs...
    case 1:
        mSuggestionAdapter.swapCursor(null);
        break;
    }
}
Vektor88
  • 4,841
  • 11
  • 59
  • 111

1 Answers1

1

After further testing, I decided to not use the LoaderManager and doing everything inside my onQueryTextChange method. Both the problems seem to be solved.

public boolean onQueryTextChange(String newText) {
    Log.i("TextChange", "=(" + newText + ")");
    if (newText == null || newText.isEmpty()) {
        if (null != mSuggestionAdapter)
            mSuggestionAdapter.swapCursor(null);
    } else {
        Cursor mCur = mActivity.getContentResolver().query(
                MyContentProvider.URI,
                DataSource.allColumns,
                mSelection, mSelectionArgs, null);
        if(null == mRomSuggestionAdapter){
            mRomSuggestionAdapter = new SuggestionsCursorAdapter(mActivity,mCur,0);
            searchView.setSuggestionsAdapter(mRomSuggestionAdapter);
        }
        if (null != mSuggestionAdapter)
            mSuggestionAdapter.swapCursor(mCur);
    }
    return true;
}
Vektor88
  • 4,841
  • 11
  • 59
  • 111