Поиск предложений из сетевого ресурса в коробку быстрого поиска
-
27-09-2019 - |
Вопрос
Я создаю поиск в приложении и должен иметь способ внесения предложений, которые я получаю от моего сервера в качестве JSON-массива в список предложений, которые отображаются под коробкой быстрого поиска.
Есть ли простой способ получить быструю поисковую коробку прочитать такие ресурсы?
В настоящее время я пытаюсь использовать ContentProvider, но методы интерфейса четко указывают, что необходимо запрашивать базу данных для получения предложений. Я думаю, что используя ContentProvider - это правильный способ, если вы ищете данные, которые хранятся внутри приложения. Однако я не так уверен, что это правильный путь, если вам нужно запросить сетевой ресурс.
Для меня не имеет смысла сохранять предложения, которые я получаю от сети в локальную базу данных, поскольку предложения, и уровень их достижения будут время от времени.
У кого-нибудь был этот вопрос? Или может указать мне в направлении подобного вопроса? Я не мог найти вопросы здесь на стеке, которые упомянули сетевые предложения.
Решение
Нашел решение на Developer.Android.com:
Если у вас есть предложения, которые вы получаете из сетевого местоположения, вы можете построить курсор на лету, когда вы получите результаты с вашего сервера.
Это идет внутри вашего метода ContentProvider ():
String[] columns = {
BaseColumns._ID,
SearchManager.SUGGEST_COLUMN_TEXT_1,
SearchManager.SUGGEST_COLUMN_INTENT_DATA
};
MatrixCursor cursor = new MatrixCursor(columns);
for (int i = 0; i < arr.length(); i++)
{
String[] tmp = {Integer.toString(i), arr.getString(i), arr.getString(i)};
cursor.addRow(tmp);
}
return cursor;
Курсор используется в поле Quick-Search, чтобы заполнить список предложений.
Другие советы
Вот пример SoolView с предложениями, поступающими из сетевого сервиса (я использовал модернизацию):
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_search_activity, menu);
final SearchView searchView = (SearchView) MenuItemCompat.getActionView(menu.findItem(R.id.search));
final CursorAdapter suggestionAdapter = new SimpleCursorAdapter(this,
android.R.layout.simple_list_item_1,
null,
new String[]{SearchManager.SUGGEST_COLUMN_TEXT_1},
new int[]{android.R.id.text1},
0);
final List<String> suggestions = new ArrayList<>();
searchView.setSuggestionsAdapter(suggestionAdapter);
searchView.setOnSuggestionListener(new SearchView.OnSuggestionListener() {
@Override
public boolean onSuggestionSelect(int position) {
return false;
}
@Override
public boolean onSuggestionClick(int position) {
searchView.setQuery(suggestions.get(position), false);
searchView.clearFocus();
doSearch(suggestions.get(position));
return true;
}
});
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
MyApp.autocompleteService.search(newText, new Callback<Autocomplete>() {
@Override
public void success(Autocomplete autocomplete, Response response) {
suggestions.clear();
suggestions.addAll(autocomplete.suggestions);
String[] columns = {
BaseColumns._ID,
SearchManager.SUGGEST_COLUMN_TEXT_1,
SearchManager.SUGGEST_COLUMN_INTENT_DATA
};
MatrixCursor cursor = new MatrixCursor(columns);
for (int i = 0; i < autocomplete.suggestions.size(); i++) {
String[] tmp = {Integer.toString(i), autocomplete.suggestions.get(i), autocomplete.suggestions.get(i)};
cursor.addRow(tmp);
}
suggestionAdapter.swapCursor(cursor);
}
@Override
public void failure(RetrofitError error) {
Toast.makeText(SearchFoodActivity.this, error.getMessage(), Toast.LENGTH_SHORT).show();
Log.w("autocompleteService", error.getMessage());
}
});
return false;
}
});
return true;
}
Не знаю, что люди все еще нуждаются в этом. На всякий случай, для будущих искателей. У меня была проблема с предложениями моего поиска, который не появился. После обыскания я нашел решение для этого. Я использовал залп для моего класса поставщиков контента (чтобы получить предложения из веб-API), который, казалось, не вписывался, что естественным образом настроен на Framework Provider Android. Я также обнаружил, что мой контент пробежен в потоке UI. Поэтому, если я использовал будущее волейна синхронно в нем, он замедлился (заблокировал) интерфейс, пока запрос не вернется (время ожидания). Кроме того, я обнаружил информацию в Интернете, что будущий запрос волейна должен быть запущен в другом потоке, например, в асинхронном задании, для него хорошо работать. Таким образом, это не решило мою проблему, потому что, если бы мне придется использовать его (в асинхронном задаче), я бы использовал нормальный (Async) запрос в первом месте (который был то, что я использовал тогда). Что я сделал, это было:
В моем подклассе ContentProvider я определяю интерфейс слушателя:
RecventListener Public Interface {
void onProviderResult(Cursor mCursor); void onProviderError(String errorMsg);
}
В моей деятельности (который реализовал LoaderCallbacks), я реализовал также выше интерфейса.
В моем классе приложений Singleton я определяю статическую переменную, которая используется в качестве временных данных вместе с его методами Getter / Setter:
Частный статический Hashmap TransientData = New Hashmap ();
Общественный статический объект GetTransientData (String ObjectName) {
return transientData.get(objectName);
}
Общественная статическая пустота SettransientData (String ObjectName, объект объекта) {
transientData.put(objectName, object);
}
- Теперь логика: в деятельности, до звонка getsupportloadermanager (). ИНЧИНАЛОГИ (...), Я звонил MyApplication.SettransientData («Загласитель», это) :
В классе моего контента поставщика, в запросе запроса залп, я сделал это:
Общественная пустота ONRESPONSE (ответ JSONARRAY) {
...
ResultListener requestor = (ResultListener)TheApplication.getTransientData("requestor");
if (requestor!=null) requestor.onProviderResult(mCursor);
}
Так что, когда запрос залей вернулся, он будет вызвать метод обратного вызова запроса, передавая его курсор, заполненный данными из ответа, и в свою очередь, запрос (действие) уведомляет адаптер курсора путем вызова: adapter.swapcursor (c); adapter.notifydatAsethetheded ();
Надеюсь, это поможет кому-то. Благословенна.