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 theLoaderManager
, 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 theContentProvider
).
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;
}
}