He creado una actividad de búsqueda. Ahora, quiero agregar sugerencias de búsqueda que se toman del servicio web. Quiero obtener esas sugerencias de forma asincrónica. De acuerdo con Adding Custom Suggestions, tengo que anular el método de consulta, hacer mi búsqueda de sugerencias, crear mi propio MatrixCursor y devolverlo. pero este es el problema, mi solicitud para obtener la sugerencia es asincrónica. por lo tanto, cuando el resultado vuelve de la red fuera del alcance del método de consulta.Android: ¿Cómo obtener sugerencias de búsqueda de manera asincrónica desde la web?
Respuesta
Lo más parecido que he encontrado para solucionar esto, es mediante el uso de un ContentProvider y hacer la solicitud de red en el método de su proveedor (aun cuando esto va en contra de las mejores prácticas) Query
, con el resultado de que puede crear un MatrixCursor
como se muestra here y here.
Todavía estoy buscando otras opciones como usar un SyncAdapter
, que parece abrumador con el único propósito de mostrar sugerencias que no se utilizan en ningún otro lado.
Otra opción que tomé para hacer esto de forma asincrónica es usar AutoCompleteTextView, de esta manera puedes crear un adaptador personalizado, donde puedes implementar la función getFilter
como se muestra en this answer.
Crear MatrixCursor como se muestra en los ejemplos, no resuelve el problema ya que quiero obtener las sugerencias de forma asincrónica del servidor. – toko
@toko, por favor, mira mi edición de respuestas, agregué otra opción, esa es la que tomé al final, que no bloqueará tu subproceso de interfaz de usuario mientras obtengas los datos de la web. –
el problema es que no estoy usando AutoCompleteTextView. Estoy usando el diálogo de la interfaz de búsqueda: http://developer.android.com/guide/topics/search/search-dialog.html – toko
Parece que la solicitud al proveedor de contenido de sugerencias no se ejecuta en el hilo de la interfaz de usuario, de todos modos, de acuerdo con esta respuesta: https://stackoverflow.com/a/12895381/621690. Si puede cambiar su solicitud http, puede simplemente llamarla bloqueo dentro del método de consulta. Podría ayudar a escuchar interrupciones u otras señales (tal vez personalizadas) para detener solicitudes innecesarias.
Otra opción: si no desea cambiar ninguna clase de solicitud que ya sea asincrónica (como si está utilizando Robospice), debería simplemente devolver la referencia de MatrixCursor y rellenarla más adelante. La clase AbstractCursor ya implementa el patrón Observer y envía notificaciones en caso de cambios. Si el sistema de búsqueda está escuchando, debe manejar cualquier cambio en los datos. Todavía tengo que implementarlo yo mismo, así que no puedo confirmar que funcionará tan bien como lo imagino. (Eche un vistazo a la fuente de CursorLoader para obtener más inspiración.)
Y, de todos modos, ¿no es ese el objetivo de un cursor? De lo contrario, simplemente podríamos devolver una lista con datos.
ACTUALIZACIÓN: Para mí, el uso de un MatrixCursor no funcionó. En su lugar, he implementado otras dos soluciones:
- Utilizando el AutoCompleteTextField en combinación con una subclase personalizada de ArrayAdapter que a su vez utiliza un subclase personalizada de filtro. El método
Filter#performFiltering()
(que anulo con la llamada síncrona al servicio remoto) se llama de manera asíncrona y el subproceso de la interfaz de usuario no está bloqueado. Uso del SearchWidget con SearchableActivity y un ArrayAdapter personalizado (sin filtro personalizado). Cuando la intención de búsqueda entra en juego, se inicia la solicitud remota (Robospice) y cuando se trata de vuelta a través de devolución de llamada, llamo al siguiente método personalizado en mi
ArrayAdapter<Tag>
subclase: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); } } }
Este método se encarga de desencadenar las notificaciones en el adaptador y, por lo tanto, la lista de resultados de búsqueda.
Definitivamente la idea correcta. Intento hacer exactamente esto, pero parece que las sugerencias de búsqueda de Android no escuchan los cambios del cursor. :/Específicamente, estoy llamando a 'ContentResolver.notifyChange()', pero no veo que ['SuggestionAdapter'] de Android (https://android.googlesource.com/platform/frameworks/base/+/jb- release/core/java/android/widget/SuggestionsAdapter.java) llama a 'registerContentObserver()'. ¿Algunas ideas? ¿Me estoy perdiendo algo? – ryan
Parecía la idea correcta, pero no funcionó (al menos no para mí). Actualicé mi respuesta con mis soluciones actuales. – Risadinha
gracias por la actualización! esas soluciones actuales tienen sentido para los resultados de búsqueda. Todavía estoy buscando una forma de actualizar [search _suggestions_] (http://developer.android.com/guide/topics/search/adding-custom-suggestions.html) después de que hayan sido devueltos. sospecho que puede que no haya una manera ... pero si sabes una, ¡háznoslo saber! – ryan
Aquí 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;
}
¿Puede explicar mejor su implementación? ¿Cómo funciona el método 'doSearch (suggestions.get (position))'? Gracias –
- 1. Problema de búsqueda de la vista web de Android 2.2
- 2. ¿Cómo manejar los resultados del cuadro de búsqueda rápida y las sugerencias recientes para la búsqueda?
- 3. ¿Cómo se pueden implementar las sugerencias de búsqueda/búsqueda en vivo usando Dojo?
- 4. Cómo obtener que Solr Suggester devuelva sugerencias de ortografía también
- 5. Cómo esperar el resultado de una llamada de servicio web asincrónica en ASP.NET para obtener el mejor rendimiento
- 6. Objective-C Solicitud web asincrónica con cookies
- 7. obtener el evento de clic desde la página web en mi aplicación de Android
- 8. Android cómo enfocar la búsqueda de ActionBarVer
- 9. ¿Alguna manera de ocultar elementos de la vista web? (Android)
- 10. Raspado web, raspado de pantalla, sugerencias de minería de datos?
- 11. Obtener la raíz de la aplicación web desde Spring Controller
- 12. Android AutoCompleteTextView con datos de un servicio web, problemas al mostrar la lista de sugerencias
- 13. ¿Cómo deshacerse de forma asincrónica?
- 14. ¿Cómo puedo buscar en toda la web desde la Búsqueda personalizada de Google?
- 15. ¿Hay alguna manera de obtener sugerencias de código para gtk3 y python trabajando en aptana?
- 16. Cómo obtener información de la cámara web
- 17. ¿Ejecución de la función asincrónica?
- 18. Cómo obtener una vCard (archivo .vcf) en los contactos de Android desde el sitio web
- 19. cómo obtener imágenes del servicio web a la aplicación Android
- 20. Obtener la ubicación de GPS desde el navegador web
- 21. ¿Es posible actualizar de manera asincrónica el aviso de PowerShell?
- 22. ¿Cómo usar WebClient dentro de ASP.NET MVC de forma asincrónica?
- 23. Obtener claves de una búsqueda
- 24. Obtener valor de la búsqueda C#
- 25. obtener miniaturas de un sitio web desde sus direcciones URL
- 26. ¿La mejor manera de agregar la búsqueda web completa a mi sitio?
- 27. Android: cargando una imagen desde la Web con Asynctask
- 28. Personalizar la barra de búsqueda en Android
- 29. Sugerencias para la construcción de un control TreeView en Android
- 30. ¿Cómo uso la programación asincrónica en Perl?
de búsqueda sugerencia que decir AutoCompleteTextView ?? –
No. Estoy usando el cuadro de diálogo de búsqueda de Android. como se describe en la documentación: "Al usar el cuadro de diálogo de búsqueda de Android o el widget de búsqueda, puede proporcionar sugerencias de búsqueda personalizadas que se crean a partir de datos en su aplicación". Lo que intento hacer es obtener esa sugerencia del servidor y no de DB. – toko