Question

Je construis la recherche dans une application et le besoin d'avoir un moyen de mettre les suggestions que je reçois de mon serveur comme JSON-tableau dans la liste des suggestions qui apparaît en dessous de la recherche rapide.

Y at-il un moyen facile d'avoir la boîte de recherche rapide lire ces ressources?

Actuellement, je suis en train d'utiliser un ContentProvider, mais les méthodes d'interface indiquent clairement on est censé être interroger une base de données pour obtenir les suggestions. Je suppose que l'aide d'un ContentProvider est la façon correcte si vous êtes à la recherche des données qui sont stockées dans l'application. Je ne suis pas sûr cependant qu'il est la bonne façon si vous avez besoin d'interroger une ressource réseau.

Il n'a pas de sens pour moi de sauver les suggestions que je reçois du réseau à une base de données locale, comme les suggestions et leur taux de succès varient de temps à autre.

Tout le monde a ce problème? Ou peut me diriger dans la direction d'une question similaire? Je ne pouvais pas trouver des questions ici sur la pile que les suggestions du réseau mentionné.

Était-ce utile?

La solution

trouvé la solution sur developer.android.com:

Si vous avez des suggestions que vous obtenez à partir d'un emplacement réseau, vous pouvez construire un curseur à la volée lorsque vous obtenez les résultats de votre serveur.

va à l'intérieur de votre méthode de recherche de 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;

Le curseur est l'utilisé dans la boîte de recherche rapide pour remplir une liste de suggestions.

Autres conseils

Voici un exemple de SearchView avec des suggestions provenant d'un service réseau (je 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;
}

Je ne sais pas si les gens ont encore besoin de cela. Juste au cas où, pour les chercheurs futurs. J'ai eu un problème avec les suggestions de mon SearchView, qui ne se présentent pas. Après une recherche autour, j'ai trouvé une solution pour cela. Je Volley pour ma classe de fournisseur de contenu (pour obtenir les suggestions de api web), qui semblaient ne pas tenir naturellement dans le cadre de fournisseur de contenu d'Android. J'ai aussi trouvé que mon fournisseur de contenu ne fonctionne dans le thread d'interface utilisateur. Par conséquent, si je l'avenir de Volley synchroniquement dans, il a ralenti (bloqué) l'interface utilisateur jusqu'à ce que la demande est retourné (délai d'attente). De plus, je trouve des informations sur le web que la demande d'avenir Volley doit être exécuté dans un autre fil, comme dans une tâche Async, pour qu'il fonctionne bien. Ainsi, il n'a pas résolu mon problème, parce que si je dois l'utiliser (dans une tâche async), je l'aurais utilisé demande normale (async) Volley en premier lieu à la place (ce qui était ce que je faisais à l'époque). Ce que je l'ai fait était le suivant:

  1. Dans ma sous-classe ContentProvider, je définis une interface auditeur:

    {public interface ResultListener

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

    }

  2. Dans mon activité (qui mettait en œuvre LoaderCallbacks), je mis en œuvre également au-dessus interface.

  3. Dans ma classe d'application singleton, je définir une variable statique qui est utilisé comme données transitoires, ainsi que ses méthodes de lecture / setter:

    private static HashMap transientData = new HashMap ();

    public static Object getTransientData (String objectName) {

    return transientData.get(objectName);
    

    }

    setTransientData public static void (String objectName, objet Object) {

    transientData.put(objectName, object);
    

    }

  4. maintenant la logique: Dans l'activité, avant d'appeler getSupportLoaderManager (). InitLoader (...) , J'ai appelé MyApplication.setTransientData ( "demandeur", ce) :

Dans ma classe de fournisseur de contenu, en rappel onResponse de la demande de volée, je l'ai fait:

onResponse public void (réponse JSONArray) {

  ...

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

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

}

Alors que lorsque la demande de volée retournée, elle déclenche la méthode de rappel du demandeur, en lui passant le curseur rempli de données de la réponse, et à son tour le demandeur (l'activité) a informé l'adaptateur du curseur en appelant:       adapter.swapCursor (c);       adapter.notifyDataSetChanged ();

Espérons que cela aide quelqu'un. Soyez bénis.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top