Pregunta

Estoy construyendo la búsqueda en una aplicación y necesidad de contar con una forma de poner las sugerencias que me sale de mi servidor como JSON-matriz en la lista de sugerencias que se muestra debajo del cuadro de búsqueda rápida.

¿Hay una manera fácil de tener el cuadro de búsqueda rápida leer tales recursos?

Actualmente estoy tratando de utilizar un ContentProvider, pero los métodos de interfaz indicar claramente uno se supone que la consulta de una base de datos para obtener las sugerencias. Creo que el uso de un ContentProvider es la forma correcta si usted está buscando los datos que se almacena dentro de la aplicación. No estoy tan seguro sin embargo, que es la manera correcta si necesita consultar un recurso de red.

No tiene sentido para que salve las sugerencias que recibe de la red a una base de datos local, como las sugerencias y su tasa de éxito pueden variar de vez en cuando.

Cualquier persona tenía este problema? O me puede apuntar en la dirección de una pregunta similar? No pude encontrar preguntas aquí en la pila que se menciona sugerencias de la red.

¿Fue útil?

Solución

encontrado la solución en developer.android.com:

Si tiene alguna sugerencia que se obtiene de una ubicación de red, se puede construir un cursor sobre la marcha cuando se obtiene los resultados de su servidor.

Esto va dentro de su método de consulta 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;

El cursor se la utiliza en la casilla de búsqueda rápida para llenar una lista de sugerencias.

Otros consejos

Este es un ejemplo de SearchView con sugerencias procedentes de un servicio de red (utilicé reequipamiento):

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

No sé si la gente todavía necesita esto. Por si acaso, para los investigadores futuros. He tenido un problema con las sugerencias de mi SearchView, que no se presentaron. Después buscado en torno, he encontrado una solución para esto. Solía ??voleo para mi clase de proveedor de contenidos (para obtener las sugerencias de Web API), que parecían no encajar de forma natural en el marco proveedor de contenido de Android. También encontré que mi proveedor de contenido se ejecuta en el hilo de interfaz de usuario. Por lo tanto, si utiliza el Futuro de voleo de forma sincrónica en el mismo, se ralentizó (bloqueado) la interfaz de usuario hasta que la solicitud devuelta (tiempo de espera). Además, encontré información en la web que la solicitud Futuro de voleo debe ejecutarse en otro hilo, tal como en una tarea asíncrona, para que funcione bien. Por lo tanto, no resolvió mi problema, porque si yo tendría que usarlo (en una tarea asíncrona), que habría utilizado petición normal (asíncrono) en el primer lugar del voleo lugar (que era lo que solía continuación). Lo que hice fue lo siguiente:

  1. En mi subclase ContentProvider, defino una interfaz de escucha:

    interfaz pública ResultListener {

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

    }

  2. En mi actividad (que implementa LoaderCallbacks), I implementado también por encima de la interfaz.

  3. En mi clase de aplicación único, que definen una variable estática que se utiliza como datos transitorios, junto con sus métodos de captador /:

    estática privado HashMap transientData = new HashMap ();

    Objeto public static getTransientData (String nomObjeto) {

    return transientData.get(objectName);
    

    }

    pública setTransientData static void (String nomObjeto, objeto Object) {

    transientData.put(objectName, object);
    

    }

  4. ahora la lógica: En la actividad, antes de llamar a getSupportLoaderManager (). InitLoader (...) Llamé MyApplication.setTransientData ( "solicitante", esto)

En la clase de mi proveedor de contenido, en la devolución de llamada onResponse de la solicitud de descarga, que hice esto:

onResponse pública vacío (respuesta JSONArray) {

  ...

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

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

}

Así que cuando la solicitud volea regresó, se disparará el método de devolución de llamada del solicitante, pasándole el cursor llenado con los datos de la respuesta, ya su vez el solicitante (la actividad) notificó el adaptador cursor llamando a:       adapter.swapCursor (c);       adapter.notifyDataSetChanged ();

Espero que esto ayude a alguien. Sean bendecidos.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top