Поиск предложений из сетевого ресурса в коробку быстрого поиска

StackOverflow https://stackoverflow.com/questions/4264589

Вопрос

Я создаю поиск в приложении и должен иметь способ внесения предложений, которые я получаю от моего сервера в качестве 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) запрос в первом месте (который был то, что я использовал тогда). Что я сделал, это было:

  1. В моем подклассе ContentProvider я определяю интерфейс слушателя:

    RecventListener Public Interface {

      void onProviderResult(Cursor mCursor);
    
      void onProviderError(String errorMsg);
    

    }

  2. В моей деятельности (который реализовал LoaderCallbacks), я реализовал также выше интерфейса.

  3. В моем классе приложений Singleton я определяю статическую переменную, которая используется в качестве временных данных вместе с его методами Getter / Setter:

    Частный статический Hashmap TransientData = New Hashmap ();

    Общественный статический объект GetTransientData (String ObjectName) {

    return transientData.get(objectName);
    

    }

    Общественная статическая пустота SettransientData (String ObjectName, объект объекта) {

    transientData.put(objectName, object);
    

    }

  4. Теперь логика: в деятельности, до звонка getsupportloadermanager (). ИНЧИНАЛОГИ (...), Я звонил MyApplication.SettransientData («Загласитель», это) :

В классе моего контента поставщика, в запросе запроса залп, я сделал это:

Общественная пустота ONRESPONSE (ответ JSONARRAY) {

  ...

  ResultListener requestor =   (ResultListener)TheApplication.getTransientData("requestor");

  if (requestor!=null) requestor.onProviderResult(mCursor);

}

Так что, когда запрос залей вернулся, он будет вызвать метод обратного вызова запроса, передавая его курсор, заполненный данными из ответа, и в свою очередь, запрос (действие) уведомляет адаптер курсора путем вызова: adapter.swapcursor (c); adapter.notifydatAsethetheded ();

Надеюсь, это поможет кому-то. Благословенна.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top