Implementación del widget de la barra de herramientas de Android en ListFragment
Actualmente tengo mi aplicación configurada con un ListFragment
a la izquierda y un DetailsFragment
a la derecha (similar al diseño de la tableta de abajo).
- Cómo buscar una cadena en google usando el navegador predeterminado
- Sugerencias de búsqueda personalizada en el widget de búsqueda
- ¿Son posibles varias clases SearchRecentSuggestionsProvider en la aplicación de Android?
- Icono de la vista de búsqueda
- Cambiar los fondos de ActionBar y SearchView
En la barra de acción tengo un widget de búsqueda que cuando se envía un término de búsqueda debe actualizar el contenido de la lista (en el ListFragment). He estado siguiendo la guía de búsqueda en android dev ( http://developer.android.com/guide/topics/search/search-dialog.html ) pero estoy teniendo problemas para obtener la búsqueda para actualizar la lista en la misma actividad.
He logrado obtener alguna forma de implementación trabajando llamando a una nueva actividad cuando se envía el término de búsqueda, pero esto hace que el botón de retroceso se comporte de forma extraña (es decir, presiona atrás y se pasa a la actividad anterior con el widget de búsqueda que muestra el término de búsqueda ).
He añadido las líneas de intención al manifiesto como sigue
<intent-filter> <action android:name="android.intent.action.SEARCH" /> </intent-filter> <meta-data android:name="android.app.searchable" android:resource="@xml/searchable"/>
¿Es posible obtener el widget de búsqueda para actualizar la lista de la actividad actual?
- SearchView en una actividad, resulta en otra
- Uso de una URL web para SUGGEST_COLUMN_ICON_1 para sugerencias de búsqueda
- Búsqueda de Android con Fragmentos
- ListView de búsqueda múltiple
- Búsqueda asistida por Android: El botón de búsqueda no invoca la actividad que se puede buscar (Otras soluciones no ayudaron)
- SearchInfo siempre saliendo null
Sí, de hecho, ese es el caso de uso "normal". Lo que hay que recordar es que el fragmento que utiliza el widget de barra de acción de búsqueda, debe ser la parte que lo registra en general, ya que el widget se destruirá junto con ese fragmento.
Aquí está cómo atarlo apropiadamente para arriba:
En su ListFragment
que se sepa que tiene opciones de menú de opciones …
@Override public void onActivityCreated(Bundle savedInstanceState) { .. setHasOptionsMenu(true); .. }
A continuación, dentro del mismo ListFragment
crear su menú de opciones mediante la sustitución de la devolución de llamada, una vez que tenga la referencia de widget SearchView, registrar una devolución de llamada QueryTextListener:
@Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { inflater.inflate(R.menu.grid_default, menu); SearchView searchView = (SearchView)menu.findItem(R.id.grid_default_search).getActionView(); searchView.setOnQueryTextListener(queryListener); }
Crear su widget de búsqueda a través de programación (Java) o declarativamente (XML) aquí es XML (llamado grid_default.xml, desde arriba):
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/grid_default_search" android:icon="@android:drawable/ic_menu_search" android:title="search" android:showAsAction="always" android:actionViewClass="android.widget.SearchView" /> <!-- other items or whatever --> </menu>
Ahora en tu ListFragment
necesitas crear el queryListener
registrado arriba:
private String grid_currentQuery = null; // holds the current query... final private OnQueryTextListener queryListener = new OnQueryTextListener() { @Override public boolean onQueryTextChange(String newText) { if (TextUtils.isEmpty(newText)) { getActivity().getActionBar().setSubtitle("List"); grid_currentQuery = null; } else { getActivity().getActionBar().setSubtitle("List - Searching for: " + newText); grid_currentQuery = newText; } getLoaderManager().restartLoader(0, null, MyListFragment.this); return false; } @Override public boolean onQueryTextSubmit(String query) { Toast.makeText(getActivity(), "Searching for: " + query + "...", Toast.LENGTH_SHORT).show(); return false; } };
Ahora sabes cuando una consulta se cambia o se envía, en mi ejemplo, vuelvo a consultar en cualquier momento una tecla se presiona porque mi base de datos era pequeña y rápida con los resultados, es posible que tenga que cambiar esto .. pero te darás cuenta de cómo estoy Simplemente usando el widget para establecer un campo de clase privada dentro del ListFragment
al texto actual del widget de búsqueda ( grid_currentQuery
) y luego solo llamo a getLoaderManager().restartLoader(0, null, MyListFragment.this);
Donde dentro de mi onCreateLoader
sólo estoy actualizando la consulta que usé así:
@Override public Loader<Cursor> onCreateLoader(int id, Bundle bargs) { String sort = "SortColumn ASC"; String[] grid_columns = new String[] { "ColumnA", "ColumnB", "Etc..." }; String grid_whereClause = "ColumnToSearchBy LIKE ?" if (!TextUtils.isEmpty(grid_currentQuery)) { return new CursorLoader(getActivity(), DataProvider.CONTENT_URI, grid_columns, grid_whereClause, new String[] { grid_currentQuery + "%" }, sort); } return new CursorLoader(getActivity(), DataProvider.CONTENT_URI, grid_columns, null, null, sort); }
Y eso es todo lo que realmente necesita hacer, me doy cuenta de que esto es un poco cortado, pero es así porque hay más cosas que tiene que suceder, la configuración del adaptador, empezando el cargador en primer lugar con getLoaderManager().initLoader(0, null, this);
Y todo el resto de las devoluciones de llamada del cargador que necesitan ser manejadas … pero si usted está siguiendo las mejores prácticas fijadas por la gente del androide, (usar LoaderManager
s en su ListActivity
s y ListFragments
s debe ser bastante fácil para usted. ..
Espero que esto ayude a sentirse libre de pedir aclaraciones en los comentarios si necesita -ck