Android: Wie bekomme ich Suchvorschläge asynchron aus dem Internet?

Ich habe eine durchsuchbare Aktivität erstellt. Jetzt möchte ich Suchvorschläge hinzufügen, die aus dem Webdienst genommen werden. Ich möchte diese Vorschläge asynchron bekommen. Nach Hinzufügen von benutzerdefinierten Anregungen muss ich die Abfrage-Methode überschreiben, meine Vorschläge suchen, meinen eigenen MatrixCursor erstellen und ihn zurückgeben. Aber das ist das Problem, meine Bitte um den Vorschlag zu bekommen ist eine asynchrone. Also wenn das Ergebnis wieder aus dem Netz ist, ist es außerhalb der Abfragemethode.

  • Android SearchRecentSuggestions - Vorschläge werden bei der Eingabe von SearchView nicht angezeigt
  • SearchView Filtern und Anlegen von Vorschlägen
  • Android - Vermeidung von Textkürzung in SearchView-Vorschlägen?
  • 3 Solutions collect form web for “Android: Wie bekomme ich Suchvorschläge asynchron aus dem Internet?”

    Es scheint, dass die Anforderung an den Vorschlag Content Provider nicht auf dem UI-Thread laufen, sowieso, nach dieser Antwort: https://stackoverflow.com/a/12895381/621690 . Wenn Sie Ihre http-Anfrage ändern können, können Sie es einfach in der Abfrage-Methode blockieren. Könnte helfen, auf Unterbrechungen oder andere Signale zu hören (benutzerdefinierte vielleicht), um unnötige Anfragen zu stoppen.

    Eine weitere Option – wenn du keine Anforderungsklassen ändern willst, die bereits asynchron sind (wie wenn du Robospice benutzt) – soll einfach die MatrixCursor-Referenz zurückgeben und später füllen. Die AbstractCursor-Klasse implementiert bereits das Observer-Muster und sendet im Falle von Änderungen Benachrichtigungen aus. Wenn das Suchsystem zuhört, sollte es Änderungen an den Daten bewältigen. Ich habe das noch einmal umzusetzen, damit ich nicht bestätigen kann, dass es so schön aussieht, wie ich es mir vorstelle. (Schauen Sie sich die Quelle von CursorLoader für mehr Inspiration an.)

    Und sowieso ist das nicht der ganze Punkt eines Cursors? Ansonsten könnten wir einfach eine Liste mit Daten zurückgeben.

    UPDATE: Für mich hat ich mit einem MatrixCursor nicht geklappt. Stattdessen habe ich zwei weitere Lösungen implementiert:

    1. Verwenden Sie das AutoCompleteTextField in Kombination mit einer benutzerdefinierten Unterklasse von ArrayAdapter, die selbst eine benutzerdefinierte Unterklasse von Filter verwendet. Die Methode Filter#performFiltering() (die ich mit dem synchronen Aufruf zum Remote Service überschreibe) wird asynchron aufgerufen und der UI Thread ist nicht gesperrt.
    2. Verwenden des SearchWidget mit einer SearchableActivity und einem benutzerdefinierten ArrayAdapter (ohne benutzerdefinierten Filter). Wenn die Suchabsicht hereinkommt, wird die Fernanforderung gestartet (Robospice) und wenn es über Callback zurückkommt, rufe ich die folgende benutzerdefinierte Methode auf meiner ArrayAdapter<Tag> Unterklasse an:

       public void addTags(List<Tag> items) { if (items != null && items.size() > 0) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { super.setNotifyOnChange(false); for (Tag tag : items) { super.add(tag); } super.notifyDataSetChanged(); } else { super.addAll(items); } } } 

    Diese Methode kümmert sich darum, die Meldungen am Adapter und damit die Suchergebnisliste auszulösen.

    Hier ist ein Beispiel für SearchView mit Anregungen aus einem Netzwerk-Service (ich habe Retrofit):

     @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; } 

    Das nächste, was ich gefunden habe, um dies zu lösen, ist mit einem ContentProvider und die Netzwerkanforderung auf die Query Methode Ihres Providers (auch wenn dies gegen die bewährten Praktiken geht), mit dem Ergebnis können Sie einen MatrixCursor erstellen, wie es hier zeigt Und hier

    Ich bin immer noch auf der Suche nach anderen Optionen wie mit einem SyncAdapter , die scheint überwältigend für den Zweck nur Vorschläge, die nicht anderswo verwendet werden.

    Eine weitere Option, die ich getan habe, um dies asynchron zu tun, ist ein AutoCompleteTextView verwenden, so können Sie einen benutzerdefinierten Adapter erstellen, wo Sie die getFilter Funktion implementieren können, wie es in dieser Antwort gezeigt wird .

    Das Android ist ein Google Android Fan-Website, Alles ├╝ber Android Phones, Android Wear, Android Dev und Android Spiele Apps und so weiter.