Domanda

Sto costruendo la ricerca in un'applicazione e hanno bisogno di avere un modo di mettere i suggerimenti che ricevo dal mio server come un JSON-array nella lista di suggerimenti che è visualizzato sotto la casella di ricerca rapida.

C'è un modo semplice per avere la casella di ricerca rapida visione di tali risorse?

Al momento sto cercando di usare un ContentProvider, ma i metodi di interfaccia indicano chiaramente uno dovrebbe essere l'interrogazione di un database per ottenere i suggerimenti. Credo che con un ContentProvider è il modo corretto se siete alla ricerca dei dati che viene memorizzato all'interno dell'applicazione. Io non sono così sicuro però, che sia la strada giusta se avete bisogno di interrogare una risorsa di rete.

Non ha senso per me per salvare i suggerimenti che ricevo da rete per un database locale, come i suggerimenti e il loro tasso di successo può variare di volta in volta.

Chiunque ha avuto questo problema? O mi può puntare nella direzione di una domanda simile? Non riuscivo a trovare domande qui sulla pila che menzionato suggerimenti di rete.

È stato utile?

Soluzione

Trovato la soluzione su developer.android.com:

Se hai dei suggerimenti che si ottiene da un percorso di rete, è possibile costruire un cursore al volo quando si ottengono i risultati dal server.

Questo va all'interno del vostro metodo di interrogazione di 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;

Il cursore è il utilizzato nella casella di ricerca rapida per riempire una lista di suggerimenti.

Altri suggerimenti

Ecco un esempio di SearchView con suggerimenti provenienti da un servizio di rete (io ho usato 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;
}

Non so se la gente ancora bisogno di questo. Nel caso in cui, per i ricercatori futuri. Ho avuto un problema con i suggerimenti del mio SearchView, che non si fece vedere. Dopo cercato in giro, ho trovato una soluzione per questo. Ho usato Volley per il mio contenuto di classe fornitore (per ottenere i suggerimenti da web API), che sembravano non per adattarsi naturalmente in quadro fornitore di contenuti di Android. Ho anche scoperto che il mio fornitore di contenuti viene eseguito nel thread UI. Quindi, se ho usato Future di Volley sincrono in esso, è rallentato (bloccato) l'interfaccia utente fino a quando la richiesta è tornato (timeout). Inoltre, ho trovato informazioni in tutto il web che la richiesta futura di Volley deve essere eseguito in un altro thread, come ad esempio in un compito asincrona, per farlo funzionare bene. Quindi, non ha risolto il mio problema, perché se avrei dovuto usarla (in un task asincrona), avrei usato normale (asincrona) la richiesta di Volley, in primo luogo, invece (che era quello che ho usato allora). Quello che ho fatto è stato questo:

  1. Nel mio ContentProvider sottoclasse, definisco un'interfaccia ascoltatore:

    interfaccia pubblica ResultListener {

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

    }

  2. Nella mia attività (che implementato LoaderCallbacks), ho realizzato anche al di sopra di interfaccia.

  3. Nella mia classe di applicazione Singleton, Mi definisco una variabile statica che viene usato come dati transitori, insieme ai suoi getter / setter:

    private static HashMap transientData = new HashMap ();

    Oggetto public static getTransientData (String objectName) {

    return transientData.get(objectName);
    

    }

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

    transientData.put(objectName, object);
    

    }

  4. ora la logica: Nell'attività, prima di chiamare getSupportLoaderManager (). InitLoader (...) , Ho chiamato MyApplication.setTransientData ( "richiedente", questo) :

In classe i miei contenuti del provider, nel callback onResponse della richiesta di pallavolo, ho fatto questo:

onResponse public void (risposta JSONArray) {

  ...

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

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

}

In modo che quando la richiesta volley restituito, innescherà metodo di callback del richiedente, passando il cursore riempita con i dati della risposta, ed a sua volta il richiedente (l'attività) ha notificato l'adattatore cursore chiamando:       adapter.swapCursor (c);       adapter.notifyDataSetChanged ();

Spero che questo aiuti qualcuno. Siate benedetti.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top