Правильное отображение предложений SearchView
Я недавно добавил SearchView
к моему заявлению (предоставленному в support-v7
библиотека). В моем случае кнопка отправки никогда не должна начинать новый Intent
с ACTION_SEARCH
Я просто хочу показать список предложений, которые пользователь может просмотреть, и если щелкнуть одно из них, произойдет какое-то действие.
Я думаю, что все правильно настроено, но у меня есть две большие проблемы:
- В первый раз, когда я что-то набираю, даже если все события сработали (я использовал некоторые распечатки журнала, чтобы проверить это), список предложений не отображается, я должен очистить текст поиска и возобновить запись, затем предложения отображаются, Это происходит только в первый раз, когда я что-то ищу. Если я закрою и снова открою
SearchView
, показывает предложения с первой попытки. - Чтобы загрузить предложения, я запрашиваю
ContentProvider
сквозьLoaderManager
и если я наберу слишком быстро, приложение вылетает, сообщая, что я пытаюсь заново открыть уже закрытый объект (я думаю, что курсор, который я получаю, запрашиваяContentProvider
).
Что я должен изменить в своем коде, чтобы он работал правильно?
Код:
в 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);
мой 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;
}
мой 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;
}
мой 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;
}
}
И наконец мой onLoaderReset
:
@Override
public void onLoaderReset(Loader<Cursor> loader) {
switch (loader.getId()) {
//Other Loader IDs...
case 1:
mSuggestionAdapter.swapCursor(null);
break;
}
}
1 ответ
Решение
После дальнейшего тестирования я решил не использовать LoaderManager
и делать все внутри моего onQueryTextChange
метод. Обе проблемы, кажется, решены.
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;
}