Cómo configurar la interfaz de búsqueda

Prueba la forma de Compose
Jetpack Compose es el kit de herramientas de IU recomendado para Android. Obtén información para agregar la funcionalidad de búsqueda en Compose.

Te recomendamos que uses el widget SearchView como un elemento en la barra de la app para proporcionar la funcionalidad de búsqueda en tu app. Al igual que con todos los elementos de la barra de la app, puedes definir el SearchView para que se muestre en todo momento o solo cuando haya espacio. También puedes definirlo como una acción que se puede contraer, que muestra el SearchView como un ícono inicialmente y, luego, ocupa toda la barra de la app como un campo de búsqueda cuando el usuario presiona el ícono.

Cómo agregar SearchView a la barra de la app

Para agregar un widget SearchView a la barra de la app, crea un archivo en tu proyecto llamado res/menu/options_menu.xml 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, recomendamos usar el atributo collapsibleActionView para 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="androidx.appcompat.widget.SearchView" />
</menu>

Si quieres un ícono de búsqueda más accesible, crea un archivo ic_search.xml en la carpeta /res/drawable y, luego, incluye el siguiente código en él:

<vector
    android:height="24dp"
    android:tint="#000000"
    android:viewportHeight="24"
    android:viewportWidth="24"
    android:width="24dp"
    xmlns:android="http://schemas.android.com/apk/res/android">
        <path android:fillColor="@android:color/white" android:pathData="M15.5,14h-0.79l-0.28,-0.27C15.41,12.59 16,11.11 16,9.5 16,5.91 13.09,3 9.5,3S3,5.91 3,9.5 5.91,16 9.5,16c1.61,0 3.09,-0.59 4.23,-1.57l0.27,0.28v0.79l5,4.99L20.49,19l-4.99,-5zM9.5,14C7.01,14 5,11.99 5,9.5S7.01,5 9.5,5 14,7.01 14,9.5 11.99,14 9.5,14z"/>
</vector>

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
}

Cuando se ejecuta la app, se genera algo como lo siguiente:

Una imagen que muestra una pantalla vacía con un ícono de búsqueda en la barra superior de la app
Figura 1: Un ícono de búsqueda en la barra superior de la app.

SearchView aparece en la barra de la app, pero no es funcional. Si presionas el ícono de búsqueda, verás algo como lo siguiente:

Una imagen que muestra la vista de búsqueda en acción
Figura 2: SearchView en acción.

Para que SearchView sea funcional, debes definir cómo se comporta SearchView.

Cómo crear una configuración de búsqueda

Una configuración de búsqueda especifica cómo se comporta SearchView y se define en un archivo res/xml/searchable.xml. Una configuración de búsqueda debe contener, como mínimo, un atributo android:label que tenga el mismo valor que el atributo android:label del elemento <application> o <activity> en tu manifiesto de Android. Sin embargo, también se recomienda agregar un atributo android:hint para 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 app, declara un elemento <meta-data> que apunte al archivo res/xml/searchable.xml. Declara el elemento en un <activity> en el que deseas mostrar el SearchView.

<activity
android:name=".SearchResultsActivity"
android:exported="false"
android:label="@string/title_activity_search_results"
android:launchMode="singleTop"
android:theme="@style/Theme.AppCompat.Light">
    <intent-filter>
        <action android:name="android.intent.action.SEARCH" />
    </intent-filter>
    <meta-data
        android:name="android.app.searchable"
        android:resource="@xml/searchable" />
</activity>

En el método onCreateOptionsMenu() que crees, asocia la configuración de búsqueda con SearchView llamando a setSearchableInfo(SearchableInfo):

Kotlin

override fun onCreateOptionsMenu(menu: Menu): Boolean {
    menuInflater.inflate(R.menu.options_menu, menu)

    val searchManager = getSystemService(Context.SEARCH_SERVICE) as SearchManager
    val searchView = menu.findItem(R.id.search).actionView as SearchView
    val component = ComponentName(this, SearchResultsActivity::class.java)
    val searchableInfo = searchManager.getSearchableInfo(component)
    searchView.setSearchableInfo(searchableInfo)
    return true
}

La llamada a getSearchableInfo() obtiene un objeto SearchableInfo que se crea a partir del archivo en formato XML de la configuración de búsqueda. Cuando la configuración de búsqueda se asocia correctamente con tu SearchView y el usuario envía una consulta, SearchView inicia una actividad con el intent ACTION_SEARCH. Luego, necesitas una actividad que pueda filtrar este intent y controlar la búsqueda.

Cómo crear una actividad que permite búsquedas

La actividad que permite búsquedas actúa como filtro para el intent ACTION_SEARCH y realiza la búsqueda en un conjunto de datos. Para 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().

Kotlin

class SearchResultsActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_search_results)
        handleIntent(intent)
    }

    override fun onNewIntent(intent: Intent) {
        super.onNewIntent(intent)
        handleIntent(intent)
    }

    private fun handleIntent(intent: Intent) {
        if (Intent.ACTION_SEARCH == intent.action) {
            val query = intent.getStringExtra(SearchManager.QUERY)
            Log.d("SEARCH", "Search query was: $query")
        }
    }
}

Ahora, SearchView puede aceptar la consulta del usuario y comenzar tu actividad de búsqueda con el intent ACTION_SEARCH.

Después de obtener la búsqueda, puedes pasarla a ViewModel, donde puedes usarla en otras capas de tu arquitectura para recuperar los resultados de la búsqueda que se mostrarán.