Cómo crear una interfaz de búsqueda

Prueba hacerlo con Compose
Jetpack Compose es el kit de herramientas de IU recomendado para Android. Aprende a agregar funcionalidad de búsqueda en Compose.

Cuando quieras agregar la funcionalidad de búsqueda a tu app, Android te ayudará a implementar la interfaz de usuario con un diálogo de búsqueda que aparece en la parte superior de la ventana de actividad o un widget de búsqueda que puedes insertar en el diseño. Tanto el diálogo como el widget de búsqueda pueden entregar la búsqueda del usuario a una actividad específica en tu app. De esta manera, el usuario puede iniciar una búsqueda desde cualquier actividad donde esté disponible el diálogo o widget de búsqueda, y el sistema inicia la actividad apropiada para realizar la búsqueda y presentar resultados.

Otras funciones disponibles para el diálogo y el widget de búsqueda incluyen las siguientes:

  • Búsqueda por voz
  • Sugerencias de búsqueda basadas en consultas recientes
  • Sugerencias de búsqueda que coinciden con resultados reales en los datos de tu app

En este documento, se muestra cómo configurar tu app para proporcionar una interfaz de búsqueda asistida por el sistema Android a fin de entregar consultas de búsqueda, utilizando el diálogo o el widget de búsqueda.

Recursos relacionados:

Conceptos básicos

Antes de comenzar, decide si quieres implementar tu interfaz de búsqueda con el diálogo o el widget de búsqueda. Ambos proporcionan las mismas funciones de búsqueda, pero de maneras ligeramente distintas:

  • El diálogo de búsqueda es un componente de IU que controla el sistema Android. Cuando el usuario lo activa, el diálogo de búsqueda aparece en la parte superior de la actividad.

    El sistema Android controla todos los eventos en el diálogo de búsqueda. Cuando el usuario envía una consulta, el sistema la entrega a la actividad que especificas para administrar las búsquedas. El diálogo también puede proporcionar sugerencias de búsqueda mientras el usuario escribe.

  • El widget de búsqueda es una instancia de SearchView que puedes colocar en cualquier lugar del diseño. De forma predeterminada, el widget de búsqueda se comporta como un widget EditText estándar y no hace nada, pero puedes configurarlo para que el sistema Android maneje todos los eventos de entrada, envíe consultas a la actividad apropiada y proporcione sugerencias de búsqueda, igual que el diálogo de búsqueda.

Cuando el usuario ejecuta una búsqueda desde el diálogo o widget de búsqueda, el sistema crea un Intent y almacena la consulta del usuario allí. Luego, el sistema inicia la actividad que declaraste para manejar las búsquedas (la "actividad de búsqueda") y entrega el intent. Si quieres configurar tu app para este tipo de búsqueda asistida, necesitas lo siguiente:

  • Una configuración de búsqueda
    Un archivo XML que configura algunos ajustes para el diálogo o widget de búsqueda. Incluye parámetros de configuración para funciones como la búsqueda por voz, la sugerencia de búsqueda y el texto de sugerencias para el cuadro de búsqueda.
  • Una actividad de búsqueda
    La Activity que recibe la búsqueda, busca en tus datos y muestra los resultados de la búsqueda.
  • Una interfaz de búsqueda proporcionada por cualquiera de las siguientes opciones:
    • El diálogo de búsqueda
      De forma predeterminada, el diálogo de búsqueda está oculto. Aparece en la parte superior de la pantalla cuando llamas a onSearchRequested() cuando el usuario presiona tu botón de búsqueda.
    • Un widget de SearchView
      El uso del widget de búsqueda te permite colocar el cuadro de búsqueda en cualquier lugar de tu actividad, incluso como una vista de acción en la barra de la app.

En el resto de este documento, se muestra cómo crear la configuración de búsqueda y la actividad de búsqueda, y cómo implementar una interfaz de búsqueda con el diálogo o widget de búsqueda.

Crea una configuración de búsqueda

Lo primero que necesitas es un archivo XML llamado configuración de búsqueda. Configura ciertos aspectos de la IU del diálogo o widget de búsqueda, y define la forma en que se comportan las funciones, como las sugerencias y la búsqueda por voz. Este archivo suele denominarse searchable.xml y debe guardarse en el directorio del proyecto res/xml/.

El archivo de configuración de búsqueda debe incluir el elemento <searchable> como su nodo raíz y especificar uno o más atributos, como se muestra en el siguiente ejemplo:

<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
    android:label="@string/app_label"
    android:hint="@string/search_hint" >
</searchable>

El atributo android:label es el único atributo requerido. Apunta a un recurso de cadena, que debe ser el nombre de la app. Esta etiqueta no está visible para el usuario hasta que habilitas las sugerencias de búsqueda para el cuadro de búsqueda rápida, momento en el que la etiqueta aparece en la lista de elementos de búsqueda en la configuración del sistema.

Aunque no es obligatorio, te recomendamos que siempre incluyas el atributo android:hint, que proporciona una cadena de sugerencia en el cuadro de búsqueda antes de que los usuarios ingresen una consulta. La sugerencia es importante porque proporciona pistas importantes a los usuarios sobre lo que pueden buscar.

El elemento <searchable> acepta varios otros atributos. Sin embargo, no necesitarás la mayoría de los atributos hasta que agregues funciones como sugerencias de búsqueda y búsqueda por voz. Para obtener información detallada sobre el archivo de configuración de búsqueda, consulta el documento de referencia Configuración de búsqueda.

Cómo crear una actividad de búsqueda

Una actividad de búsqueda es la Activity en tu app que realiza búsquedas basadas en una cadena de búsqueda y presenta los resultados de la búsqueda.

Cuando el usuario ejecuta una búsqueda en el diálogo o widget de búsqueda, el sistema inicia la actividad de búsqueda y le envía la búsqueda en un Intent con la acción ACTION_SEARCH. La actividad de búsqueda recupera la consulta del elemento adicional de QUERY del intent, busca en los datos y presenta los resultados.

Debido a que puedes incluir el diálogo o widget de búsqueda en cualquier otra actividad de tu app, el sistema debe saber cuál es la actividad de búsqueda para poder entregar la búsqueda correctamente. Por lo tanto, primero debes declarar tu actividad de búsqueda en el archivo de manifiesto de Android.

Cómo declarar una actividad de búsqueda

Si todavía no tienes una, crea una Activity que realice búsquedas y presente resultados. No es necesario que implementes la funcionalidad de búsqueda; solo crea una actividad que puedas declarar en el manifiesto. Dentro del elemento <activity> del manifiesto, haz lo siguiente:

  1. Declara la actividad para aceptar el intent ACTION_SEARCH en un elemento <intent-filter>.
  2. Especifica la configuración de búsqueda que se usará en un elemento <meta-data>.

Esto se muestra en el siguiente ejemplo:

<application ... >
    <activity android:name=".SearchableActivity" >
        <intent-filter>
            <action android:name="android.intent.action.SEARCH" />
        </intent-filter>
        <meta-data android:name="android.app.searchable"
                   android:resource="@xml/searchable"/>
    </activity>
    ...
</application>

El elemento <meta-data> debe incluir el atributo android:name con un valor de "android.app.searchable" y el atributo android:resource con una referencia al archivo de configuración de búsqueda. En el ejemplo anterior, hace referencia al archivo res/xml/searchable.xml.

Hacer una búsqueda

Después de declarar tu actividad de búsqueda en el manifiesto, sigue este procedimiento para realizar una búsqueda en ella:

  1. Recibe la búsqueda.
  2. Busca tus datos.
  3. Presenta los resultados.

Recepción de la consulta

Cuando un usuario ejecuta una búsqueda desde el widget o diálogo de búsqueda, el sistema inicia la actividad de búsqueda y le envía un intent ACTION_SEARCH. Este intent lleva la búsqueda en la cadena de QUERY adicional. Verifica este intent cuando comience la actividad y extrae la cadena. Por ejemplo, a continuación, se muestra cómo puedes obtener la búsqueda cuando comienza la actividad de búsqueda:

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.search)

    // Verify the action and get the query.
    if (Intent.ACTION_SEARCH == intent.action) {
        intent.getStringExtra(SearchManager.QUERY)?.also { query ->
            doMySearch(query)
        }
    }
}

Java

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.search);

    // Get the intent, verify the action, and get the query.
    Intent intent = getIntent();
    if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
      String query = intent.getStringExtra(SearchManager.QUERY);
      doMySearch(query);
    }
}

La cadena QUERY siempre se incluye con el intent ACTION_SEARCH. En el ejemplo anterior, se recupera la consulta y se pasa a un método doMySearch() local donde se realiza la operación de búsqueda real.

Cómo buscar tus datos

El proceso de almacenar y buscar datos es único para tu app. Puedes almacenar y buscar datos de muchas maneras, pero en este documento no se muestra cómo hacerlo. Ten en cuenta cómo almacenas y buscas tus datos en función de tus necesidades y tu formato de datos. A continuación, se incluyen algunas sugerencias que puedes aplicar:

  • Si los datos se almacenan en una base de datos SQLite en el dispositivo, realizar una búsqueda en el texto completo (mediante FTS3, en lugar de una consulta LIKE) puede proporcionar una búsqueda más sólida en los datos de texto y producir resultados considerablemente más rápido. Consulta sqlite.org para obtener información sobre FTS3 y la clase SQLiteDatabase para obtener información sobre SQLite en Android.
  • Si los datos se almacenan en línea, el rendimiento de búsqueda percibido puede estar inhibido por la conexión de datos del usuario. Tal vez quieras mostrar un indicador de progreso hasta que aparezcan los resultados de la búsqueda. Consulta android.net para obtener una referencia de las APIs de red y ProgressBar para obtener información acerca de cómo mostrar un indicador de progreso.

Presenta los resultados

Independientemente de dónde se encuentren tus datos y cómo los busques, te recomendamos que muestres los resultados de la búsqueda en la actividad de búsqueda con un Adapter. De esta manera, puedes presentar todos los resultados de la búsqueda en un RecyclerView. Si tus datos provienen de una consulta de base de datos SQLite, puedes aplicar los resultados a un RecyclerView usando un CursorAdapter. Si tus datos vienen en un formato diferente, puedes crear una extensión de BaseAdapter.

Un Adapter vincula cada elemento de un conjunto de datos a un objeto View. Cuando se aplica el Adapter a una RecyclerView, cada dato se inserta como una vista individual en la lista. Adapter es solo una interfaz, por lo que se necesitan implementaciones como CursorAdapter (para vincular datos de un Cursor). Si ninguna de las implementaciones existentes funciona para tus datos, puedes implementar una propia desde BaseAdapter.

Cómo usar el diálogo de búsqueda

El diálogo de búsqueda proporciona un cuadro de búsqueda flotante en la parte superior de la pantalla, con el ícono de la app a la izquierda. El diálogo de búsqueda puede proporcionar sugerencias de búsqueda a medida que el usuario escribe. Cuando el usuario ejecuta una búsqueda, el sistema envía la búsqueda a una actividad de búsqueda que realiza la búsqueda.

De manera predeterminada, el diálogo de búsqueda siempre está oculto hasta que el usuario lo activa. Tu app puede activar el diálogo de búsqueda llamando a onSearchRequested(). Sin embargo, este método no funciona hasta que habilitas el diálogo de búsqueda para la actividad.

Para habilitar el diálogo de búsqueda para realizar búsquedas, indícale al sistema qué actividad de búsqueda debe recibir búsquedas del diálogo de búsqueda. Por ejemplo, en la sección anterior sobre cómo crear una actividad de búsqueda, se crea una actividad de búsqueda llamada SearchableActivity. Si quieres que una actividad separada, como una llamada OtherActivity, muestre el diálogo de búsqueda y entregue búsquedas a SearchableActivity, declara en el manifiesto que SearchableActivity es la actividad de búsqueda que se usará para el diálogo de búsqueda en OtherActivity.

Para declarar la actividad de búsqueda del diálogo de búsqueda de una actividad, agrega un elemento <meta-data> dentro del elemento <activity> de la actividad correspondiente. El elemento <meta-data> debe incluir el atributo android:value que especifica el nombre de clase de la actividad de búsqueda y el atributo android:name con un valor de "android.app.default_searchable".

Por ejemplo, a continuación, se incluye la declaración para una actividad de búsqueda, SearchableActivity, y otra actividad, OtherActivity, que utiliza SearchableActivity para realizar búsquedas ejecutadas desde su diálogo de búsqueda:

<application ... >
    <!-- This is the searchable activity; it performs searches. -->
    <activity android:name=".SearchableActivity" >
        <intent-filter>
            <action android:name="android.intent.action.SEARCH" />
        </intent-filter>
        <meta-data android:name="android.app.searchable"
                   android:resource="@xml/searchable"/>
    </activity>

    <!-- This activity enables the search dialog to initiate searches
         in the SearchableActivity. -->
    <activity android:name=".OtherActivity" ... >
        <!-- Enable the search dialog to send searches to SearchableActivity. -->
        <meta-data android:name="android.app.default_searchable"
                   android:value=".SearchableActivity" />
    </activity>
    ...
</application>

Debido a que OtherActivity ahora incluye un elemento <meta-data> para declarar qué actividad de búsqueda usar para las búsquedas, la actividad habilita el diálogo de búsqueda. Aunque el usuario está en esta actividad, el método onSearchRequested() activa el diálogo de búsqueda. Cuando el usuario ejecuta la búsqueda, el sistema inicia SearchableActivity y le entrega el intent ACTION_SEARCH.

Si deseas que todas las actividades de tu app proporcionen el diálogo de búsqueda, inserta el elemento <meta-data> anterior como secundario del elemento <application>, en lugar de cada <activity>. De esta manera, cada actividad hereda el valor, proporciona el diálogo de búsqueda y entrega búsquedas a la misma actividad de búsqueda. Si tienes varias actividades de búsqueda, puedes anular la actividad de búsqueda predeterminada colocando una declaración <meta-data> diferente dentro de las actividades individuales.

Con el diálogo de búsqueda habilitado para tus actividades, tu app está lista para realizar búsquedas.

Cómo invocar el diálogo de búsqueda

Aunque algunos dispositivos proporcionan un botón de búsqueda exclusivo, el comportamiento del botón puede variar entre dispositivos y muchos no proporcionan ninguno. Por lo tanto, cuando uses el diálogo de búsqueda, deberás proporcionar un botón de búsqueda en la IU que active el diálogo de búsqueda llamando a onSearchRequested().

Por ejemplo, agrega un botón de búsqueda en el menú de opciones o en el diseño de la IU que llame a onSearchRequested().

También puedes habilitar la función "escribir para buscar", que activa el diálogo de búsqueda cuando el usuario comienza a escribir en el teclado. Las combinaciones de teclas se insertan en el diálogo de búsqueda. Puedes habilitar la función de escribir para buscar en tu actividad llamando a setDefaultKeyMode (o DEFAULT_KEYS_SEARCH_LOCAL) durante el método onCreate() de tu actividad.

El impacto del diálogo de búsqueda en el ciclo de vida de la actividad

El diálogo de búsqueda es un Dialog que flota en la parte superior de la pantalla. No provoca ningún cambio en la pila de actividades, por lo que, cuando aparece el diálogo de búsqueda, no se llama a ningún método de ciclo de vida, como onPause(). La actividad pierde el enfoque de entrada, ya que pasa al diálogo de búsqueda.

Si deseas recibir una notificación cuando el diálogo de búsqueda esté activado, anula el método onSearchRequested(). Cuando el sistema llama a este método, es una indicación de que la actividad pierde el enfoque de entrada con el diálogo de búsqueda. Por eso, puedes realizar cualquier trabajo apropiado para el evento, como pausar un juego. A menos que estés transmitiendo datos de contexto de búsqueda (tema que se analiza en otra sección de este documento), finaliza el método llamando a la implementación de la superclase:

Kotlin

override fun onSearchRequested(): Boolean {
    pauseSomeStuff()
    return super.onSearchRequested()
}

Java

@Override
public boolean onSearchRequested() {
    pauseSomeStuff();
    return super.onSearchRequested();
}

Si el usuario cancela la búsqueda presionando el botón Atrás, se cierra el diálogo de búsqueda y la actividad vuelve a obtener el enfoque de entrada. Puedes registrarte para recibir una notificación cuando se cierre el diálogo de búsqueda con setOnDismissListener(), setOnCancelListener() o ambos. Solo debes registrar el OnDismissListener, ya que se llama cada vez que se cierra el diálogo de búsqueda. El OnCancelListener solo corresponde a eventos en los que el usuario cerró de manera explícita el diálogo de búsqueda. Por lo tanto, no se llama cuando se ejecuta una búsqueda. Cuando se ejecuta la búsqueda, el diálogo de búsqueda desaparece automáticamente.

Si la actividad actual no es la de búsqueda, se activan los eventos del ciclo de vida normal de la actividad cuando el usuario ejecuta una búsqueda. La actividad actual recibe onPause(), como se describe en Introducción a las actividades. Sin embargo, si la actividad actual es la de búsqueda, ocurre una de dos cosas:

  • De forma predeterminada, la actividad de búsqueda recibe el intent ACTION_SEARCH con una llamada a onCreate(), y se lleva una instancia nueva de la actividad a la parte superior de la pila de actividades. Ahora hay dos instancias de tu actividad de búsqueda en la pila de actividades, por lo que, si presionas el botón Atrás, volverás a la instancia anterior de la actividad de búsqueda, en lugar de salir de la actividad de búsqueda.
  • Si configuras android:launchMode en "singleTop", la actividad de búsqueda recibe el intent ACTION_SEARCH con una llamada a onNewIntent(Intent), pasando el nuevo intent ACTION_SEARCH. Por ejemplo, a continuación, se muestra cómo puedes manejar este caso, en el que el modo de inicio de la actividad de búsqueda es "singleTop":

    Kotlin

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.search)
        handleIntent(intent)
    }
    
    override fun onNewIntent(intent: Intent) {
        super.onNewIntent(intent)
        setIntent(intent)
        handleIntent(intent)
    }
    
    private fun handleIntent(intent: Intent) {
        if (Intent.ACTION_SEARCH == intent.action) {
            intent.getStringExtra(SearchManager.QUERY)?.also { query ->
                doMySearch(query)
            }
        }
    }

    Java

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.search);
        handleIntent(getIntent());
    }
    
    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        setIntent(intent);
        handleIntent(intent);
    }
    
    private void handleIntent(Intent intent) {
        if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
          String query = intent.getStringExtra(SearchManager.QUERY);
          doMySearch(query);
        }
    }

    En comparación con el código de ejemplo en la sección sobre cómo realizar una búsqueda, todo el código para controlar el intent de búsqueda ahora está en el método handleIntent(), de modo que tanto onCreate() como onNewIntent() pueden ejecutarlo.

    Cuando el sistema llama a onNewIntent(Intent), la actividad no se reinicia, por lo que el método getIntent() devuelve el mismo intent que se recibe con onCreate(). Por eso, debes llamar a setIntent(Intent) dentro de onNewIntent(Intent): para que se actualice el intent que guarda la actividad en caso de que llames a getIntent() en el futuro.

El segundo escenario, que usa el modo de inicio "singleTop", suele ser preferible, ya que, después de que se realiza una búsqueda, el usuario podría realizar búsquedas adicionales, y no quieres que tu app cree varias instancias de la actividad de búsqueda. Te recomendamos que configures tu actividad de búsqueda en el modo de inicio "singleTop" en el manifiesto de la app, como se muestra en el siguiente ejemplo:

<activity android:name=".SearchableActivity"
          android:launchMode="singleTop" >
    <intent-filter>
        <action android:name="android.intent.action.SEARCH" />
    </intent-filter>
    <meta-data
          android:name="android.app.searchable"
          android:resource="@xml/searchable"/>
  </activity>

Cómo pasar datos de contexto de búsqueda

En algunos casos, puedes realizar las mejoras necesarias en la búsqueda dentro de la actividad de búsqueda para cada búsqueda realizada. Sin embargo, si deseas refinar los criterios de búsqueda en función de la actividad desde la cual el usuario realiza una búsqueda, puedes proporcionar datos adicionales en el intent que el sistema envía a la actividad de búsqueda. Puedes pasar los datos adicionales en el Bundle APP_DATA, que se incluye en el intent ACTION_SEARCH.

Para pasar este tipo de datos a tu actividad de búsqueda, anula el método onSearchRequested() para la actividad desde la que el usuario puede realizar una búsqueda. Luego, crea un Bundle con los datos adicionales y llama a startSearch() para activar el diálogo de búsqueda. Por ejemplo:

Kotlin

override fun onSearchRequested(): Boolean {
    val appData = Bundle().apply {
        putBoolean(JARGON, true)
    }
    startSearch(null, false, appData, false)
    return true
}

Java

@Override
public boolean onSearchRequested() {
     Bundle appData = new Bundle();
     appData.putBoolean(SearchableActivity.JARGON, true);
     startSearch(null, false, appData, false);
     return true;
 }

Si se muestra verdadero, significa que procesaste correctamente este evento de devolución de llamada y llamaste a startSearch() para activar el diálogo de búsqueda. Después de que el usuario envía una búsqueda, se entrega a tu actividad de búsqueda junto con los datos que agregas. Puedes extraer los datos adicionales del Bundle APP_DATA para refinar la búsqueda, como se muestra en el siguiente ejemplo:

Kotlin

val jargon: Boolean = intent.getBundleExtra(SearchManager.APP_DATA)?.getBoolean(JARGON) ?: false

Java

Bundle appData = getIntent().getBundleExtra(SearchManager.APP_DATA);
if (appData != null) {
    boolean jargon = appData.getBoolean(SearchableActivity.JARGON);
}

Cómo usar el widget de búsqueda

Una imagen que muestra una vista de búsqueda en la barra superior de la app

Figura 1: El widget SearchView como una vista de acción en la barra de la app

El widget de búsqueda proporciona la misma funcionalidad que el diálogo de búsqueda. Inicia la actividad correspondiente cuando el usuario ejecuta una búsqueda y puede proporcionar sugerencias de búsqueda y realizar búsquedas por voz. Si no es una opción para ti colocar el widget de búsqueda en la barra de la app, puedes colocar el widget de búsqueda en algún lugar del diseño de la actividad.

Configura el widget de búsqueda

Después de crear una configuración de búsqueda y una actividad de búsqueda, habilita la búsqueda asistida para cada SearchView llamando a setSearchableInfo() y pasando el objeto SearchableInfo que representa tu configuración de búsqueda.

Puedes obtener una referencia a la SearchableInfo llamando a getSearchableInfo() en SearchManager.

Por ejemplo, si usas un SearchView como una vista de acción en la barra de la app, habilita el widget durante la devolución de llamada onCreateOptionsMenu(), como se muestra en el siguiente ejemplo:

Kotlin

override fun onCreateOptionsMenu(menu: Menu): Boolean {
    // Inflate the options menu from XML.
    val inflater = menuInflater
    inflater.inflate(R.menu.options_menu, menu)

    // Get the SearchView and set the searchable configuration.
    val searchManager = getSystemService(Context.SEARCH_SERVICE) as SearchManager
    (menu.findItem(R.id.menu_search).actionView as SearchView).apply {
        // Assumes current activity is the searchable activity.
        setSearchableInfo(searchManager.getSearchableInfo(componentName))
        setIconifiedByDefault(false) // Don't iconify the widget. Expand it by default.
    }

    return true
}

Java

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the options menu from XML.
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.options_menu, menu);

    // Get the SearchView and set the searchable configuration.
    SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
    SearchView searchView = (SearchView) menu.findItem(R.id.menu_search).getActionView();
    // Assumes current activity is the searchable activity.
    searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
    searchView.setIconifiedByDefault(false); // Don't iconify the widget. Expand it by default.

    return true;
}

El widget de búsqueda ya está configurado y el sistema envía consultas de búsqueda a tu actividad de búsqueda. También puedes habilitar las sugerencias de búsqueda para el widget de búsqueda.

Para obtener más información sobre las vistas de acción en la barra de la app, consulta Cómo usar vistas de acción y proveedores de acción.

Otras funciones del widget de búsqueda

El widget SearchView proporciona algunas funciones adicionales que podrían interesarte:

Un botón Enviar
Por defecto, no hay ningún botón para enviar una búsqueda, por lo que el usuario debe presionar la tecla Retorno en el teclado para iniciar una búsqueda. Puedes agregar un botón "Enviar" llamando a setSubmitButtonEnabled(true).
Mejora en la definición de consultas para sugerencias de búsqueda
Cuando habilitas las sugerencias de búsqueda, por lo general, esperas que los usuarios seleccionen una sugerencia. Sin embargo, es posible que también quieran definir mejor la búsqueda sugerida. Puedes agregar un botón junto a cada sugerencia que inserte la sugerencia en el cuadro de búsqueda para que el usuario la defina mejor. Para ello, llama al setQueryRefinementEnabled(true).
La capacidad de activar o desactivar la visibilidad del cuadro de búsqueda
De manera predeterminada, el widget de búsqueda está "iconificado", es decir, representado solo por un ícono de búsqueda (una lupa). Se expande para mostrar el cuadro de búsqueda cuando el usuario presiona el ícono. Como se muestra en el ejemplo anterior, puedes mostrar el cuadro de búsqueda de forma predeterminada llamando a setIconifiedByDefault(false). También puedes alternar la apariencia del widget de búsqueda llamando a setIconified().

Hay varias otras APIs en la clase SearchView que te permiten personalizar el widget de búsqueda. Sin embargo, la mayoría de ellas se usan solo cuando administras por tu cuenta todas las entradas de los usuarios en lugar de usar el sistema Android para entregar consultas y mostrar sugerencias de búsqueda.

Cómo usar el widget y el diálogo

Si insertas el widget de búsqueda en la barra de la app como una vista de acción y lo habilitas para que aparezca en la barra de la app si hay espacio (configurando android:showAsAction="ifRoom"), es posible que el widget de búsqueda no aparezca como una vista de acción. En su lugar, es posible que aparezca un elemento de menú en el menú ampliado. Por ejemplo, cuando tu app se ejecuta en una pantalla más pequeña, es posible que no haya suficiente espacio en la barra de la app para mostrar el widget de búsqueda junto con otros elementos de acción o de navegación. Por lo tanto, el elemento de menú aparecerá en el menú ampliado. Cuando se coloca en el menú ampliado, el elemento funciona como un elemento de menú normal y no muestra la vista de acción, es decir, el widget de búsqueda.

Para solucionar este problema, el elemento de menú al que adjuntes el widget de búsqueda debe activar el diálogo de búsqueda cuando el usuario lo seleccione en el menú ampliado. Para que esto suceda, implementa onOptionsItemSelected() para controlar el elemento de menú "Buscar" y abre el diálogo de búsqueda llamando a onSearchRequested().

Para obtener más información sobre cómo funcionan los elementos de la barra de la app y cómo manejar esta situación, consulta Cómo agregar la barra de la app.

Cómo agregar la búsqueda por voz

Puedes agregar la funcionalidad de búsqueda por voz al diálogo o widget de búsqueda. Para ello, agrega el atributo android:voiceSearchMode a la configuración de búsqueda. Esto agrega un botón de búsqueda por voz que inicia un mensaje de voz. Cuando el usuario termina de hablar, la búsqueda transcrita se envía a tu actividad de búsqueda.

Esto se muestra en el siguiente ejemplo:

<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
    android:label="@string/search_label"
    android:hint="@string/search_hint"
    android:voiceSearchMode="showVoiceSearchButton|launchRecognizer" >
</searchable>

El valor showVoiceSearchButton es obligatorio para habilitar la búsqueda por voz. El segundo valor, launchRecognizer, especifica que el botón de búsqueda por voz debe iniciar un reconocedor que muestre el texto transcrito a la actividad de búsqueda.

Puedes proporcionar atributos adicionales para especificar el comportamiento de búsqueda por voz, como el idioma esperado y la cantidad máxima de resultados que se mostrarán. Consulta la referencia de Configuración de búsqueda para obtener más información sobre los atributos disponibles.

Cómo agregar sugerencias de búsqueda

Con la ayuda del sistema Android, tanto el diálogo como el widget de búsqueda pueden proporcionar sugerencias de búsqueda a medida que el usuario escribe. El sistema administra la lista de sugerencias y controla el evento cuando el usuario selecciona una sugerencia.

Puedes proporcionar dos tipos de sugerencias de búsqueda:

Sugerencias de búsquedas recientes
Estas sugerencias son palabras que el usuario utilizó antes como búsquedas en tu app. Consulta Cómo agregar sugerencias de búsqueda personalizadas para obtener más información.
Sugerencias de búsqueda personalizadas
Estas son sugerencias de búsqueda que proporcionas desde tu propia fuente de datos para ayudar a los usuarios a seleccionar de inmediato la ortografía o el elemento correctos que están buscando. Consulta Cómo agregar sugerencias de búsqueda personalizadas para obtener más información.