A partir de Android 3.0, el widget SearchView
como elemento en la barra de la app es la manera preferida de proporcionar la opción de búsqueda en tu app. Al igual que con todos los elementos de la barra de la app, puedes configurar el elemento SearchView
para que se muestre en todo momento, solo cuando haya espacio o como una acción contraíble, que inicialmente muestra SearchView
como ícono y luego usa toda la barra de la app como campo de búsqueda cuando el usuario hace clic en él.
Nota: Más adelante en esta clase, obtendrás información sobre cómo hacer que tu app admita hasta Android 2.1 (API nivel 7) para dispositivos que no son compatibles con SearchView
.
Cómo agregar la vista de búsqueda a la barra de apps
Para agregar un widget SearchView
a la barra de la app, crea un archivo llamado res/menu/options_menu.xml
en tu proyecto y agrega el siguiente código al archivo.
Este código define cómo se crea el elemento de búsqueda, por ejemplo, el ícono que se usará y el título del elemento. El atributo collapseActionView
permite que tu SearchView
se expanda para ocupar toda la barra de la app y se contraiga en un elemento normal de la barra de la app cuando no esté en uso. Debido al espacio limitado de la barra de apps en teléfonos celulares, se recomienda el uso del atributo collapsibleActionView
a fin de brindar una mejor experiencia del usuario.
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/search" android:title="@string/search_title" android:icon="@drawable/ic_search" android:showAsAction="collapseActionView|ifRoom" android:actionViewClass="android.widget.SearchView" /> </menu>
Nota: Si ya tienes un archivo XML existente para los elementos del menú, puedes agregar el elemento <item>
a ese archivo.
Para mostrar SearchView
en la barra de la app, infla el recurso del menú XML (res/menu/options_menu.xml
) en el método onCreateOptionsMenu()
de tu actividad:
Kotlin
override fun onCreateOptionsMenu(menu: Menu): Boolean { menuInflater.inflate(R.menu.options_menu, menu) return true }
Java
@Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.options_menu, menu); return true; }
Si ejecutas tu app ahora, SearchView
aparecerá en la barra de la app, pero no funcionará. A continuación, tienes que definir cómo se comporta SearchView
.
Cómo crear una configuración que permite búsquedas
Una configuración que permite búsquedas define cómo se comporta SearchView
y se define en un archivo res/xml/searchable.xml
. Como mínimo, debe contener un atributo android:label
que tenga el mismo valor que el atributo android:label
de <application> o <activity> en tu manifiesto de Android.
Sin embargo, también se recomienda agregar un atributo android:hint
a fin de que el usuario tenga una idea de lo que se ingresa en el cuadro de búsqueda:
<?xml version="1.0" encoding="utf-8"?> <searchable xmlns:android="http://schemas.android.com/apk/res/android" android:label="@string/app_name" android:hint="@string/search_hint" />
En el archivo de manifiesto de tu aplicación, declara un elemento <meta-data>
que apunte al archivo res/xml/searchable.xml
de manera que tu app sepa dónde encontrarlo. Declara el elemento en un objeto <activity>
en el que deseas mostrar el elemento SearchView
:
<activity ... > ... <meta-data android:name="android.app.searchable" android:resource="@xml/searchable" /> </activity>
En el método onCreateOptionsMenu()
que creaste antes, asocia la configuración que se puede buscar con SearchView
mediante una llamada a setSearchableInfo(SearchableInfo)
:
Kotlin
override fun onCreateOptionsMenu(menu: Menu): Boolean { menuInflater.inflate(R.menu.options_menu, menu) // Associate searchable configuration with the SearchView val searchManager = getSystemService(Context.SEARCH_SERVICE) as SearchManager (menu.findItem(R.id.search).actionView as SearchView).apply { setSearchableInfo(searchManager.getSearchableInfo(componentName)) } return true }
Java
@Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.options_menu, menu); // Associate searchable configuration with the SearchView SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE); SearchView searchView = (SearchView) menu.findItem(R.id.search).getActionView(); searchView.setSearchableInfo( searchManager.getSearchableInfo(getComponentName())); return true; }
La llamada a getSearchableInfo()
obtiene un objeto SearchableInfo
que se crea a partir del archivo XML de la configuración que permite búsquedas. Cuando la configuración que permite búsquedas se asocia de forma correcta con tu SearchView
, SearchView
inicia una actividad con el intent ACTION_SEARCH
cuando un usuario envía una consulta. Ahora necesitas una actividad que sirva como filtro para este intent y administre la búsqueda.
Cómo crear una actividad que permite búsquedas
Un elemento SearchView
intenta iniciar una actividad con ACTION_SEARCH
cuando un usuario envía una búsqueda. La actividad que permite búsquedas actúa como filtro para el intent ACTION_SEARCH
y realiza la búsqueda en algún tipo de conjunto de datos. A fin de crear una actividad que permite búsquedas, declara la actividad que quieras usar para filtrar el intent ACTION_SEARCH
:
<activity android:name=".SearchResultsActivity" ... > ... <intent-filter> <action android:name="android.intent.action.SEARCH" /> </intent-filter> ... </activity>
En tu actividad de búsqueda, administra el intent ACTION_SEARCH
. Para ello, búscalo en tu método onCreate()
.
Nota: Si tu actividad que permite búsquedas se inicia en el modo superior único (android:launchMode="singleTop"
), también controla el intent ACTION_SEARCH
en el método onNewIntent()
. En el modo superior único, solo se crea una instancia de tu actividad y las próximas llamadas que se realicen a fin de iniciar una actividad no crearán una nueva actividad en la pila. Este modo de inicio resulta útil a los usuarios porque les permite realizar búsquedas desde la misma actividad sin tener que crear una nueva instancia de actividad cada vez.
Kotlin
class SearchResultsActivity : Activity() { override fun onCreate(savedInstanceState: Bundle?) { ... handleIntent(intent) } override fun onNewIntent(intent: Intent) { ... handleIntent(intent) } private fun handleIntent(intent: Intent) { if (Intent.ACTION_SEARCH == intent.action) { val query = intent.getStringExtra(SearchManager.QUERY) //use the query to search your data somehow } } ... }
Java
public class SearchResultsActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { ... handleIntent(getIntent()); } @Override protected void onNewIntent(Intent intent) { ... handleIntent(intent); } private void handleIntent(Intent intent) { if (Intent.ACTION_SEARCH.equals(intent.getAction())) { String query = intent.getStringExtra(SearchManager.QUERY); //use the query to search your data somehow } } ... }
Si ejecutas tu app ahora, SearchView
puede aceptar la consulta del usuario y comenzar tu actividad de búsqueda con el intent ACTION_SEARCH
. A partir de aquí, eres responsable de decidir cómo almacenar y buscar tus datos en función a una búsqueda.