Configurare l'interfaccia di ricerca

Ti consigliamo di utilizzare il widget SearchView come elemento nella barra dell'app per fornire funzionalità di ricerca nell'app. Come per tutti gli elementi nella barra delle app, puoi definire il SearchView in modo che venga visualizzato sempre o solo quando c'è spazio. Puoi anche definirla come azione comprimibile, che mostra SearchView all'inizio come icona e poi occupa l'intera barra dell'app come campo di ricerca quando l'utente tocca l'icona.

Aggiungere SearchView alla barra delle app

Per aggiungere un widget SearchView alla barra dell'app, crea un file nel progetto denominato res/menu/options_menu.xml e aggiungi il seguente codice al file. Questo codice definisce come creare l'elemento di ricerca, ad esempio l'icona da utilizzare e il titolo dell'elemento. L'attributo collapseActionView consente all'elemento SearchView di espandersi fino a occupare l'intera barra dell'app e di comprimersi nuovamente in un normale elemento della barra dell'app quando non in uso. A causa dello spazio limitato nella barra dell'app sui dispositivi portatili, consigliamo di utilizzare l'attributo collapsibleActionView per offrire un'esperienza utente migliore.

<?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>

Se vuoi un'icona di ricerca più accessibile, crea un file ic_search.xml nella cartella /res/drawable e includi il seguente codice al suo interno:

<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>

Per visualizzare SearchView nella barra dell'app, gonfia la risorsa del menu XML res/menu/options_menu.xml nel metodo onCreateOptionsMenu() della tua attività:

Kotlin

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

    return true
}

L'esecuzione dell'app genera un messaggio simile al seguente:

Un&#39;immagine che mostra una schermata vuota con un&#39;icona di ricerca nella barra superiore dell&#39;app
Figura 1. Icona di ricerca nella barra superiore dell'app.

L'elemento SearchView viene visualizzato nella barra delle app dell'app, ma non funziona. Se tocchi l'icona di ricerca, vedrai un messaggio simile al seguente:

Un&#39;immagine che mostra la visualizzazione della ricerca in azione
Figura 2. SearchView in azione.

Per rendere funzionale SearchView, devi definire il comportamento di SearchView.

Crea una configurazione di ricerca

Una configurazione di ricerca specifica il comportamento di SearchView e viene definita in un file res/xml/searchable.xml. Una configurazione di ricerca deve contenere almeno un attributo android:label con lo stesso valore dell'attributo android:label dell'elemento <application> o <activity> nel file manifest Android. Tuttavia, consigliamo anche di aggiungere un attributo android:hint per dare all'utente un'idea di cosa inserire nella casella di ricerca.

<?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" />

Nel file manifest della tua app, dichiara un elemento <meta-data> che rimanda al file res/xml/searchable.xml. Dichiara l'elemento in un <activity> in cui vuoi visualizzare la 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>

Nel metodo onCreateOptionsMenu() che crei, associa la configurazione di ricerca a SearchView chiamando 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 chiamata a getSearchableInfo() ottiene un oggetto SearchableInfo creato dal file XML di configurazione della ricerca. Quando la configurazione di ricerca viene associata correttamente al tuo SearchView e l'utente invia una query, SearchView avvia un'attività con l'intent ACTION_SEARCH. Avrai quindi bisogno di un'attività che possa filtrare per questo intent e gestire la query di ricerca.

Crea un'attività disponibile per la ricerca

Un'attività disponibile per la ricerca filtra l'intent ACTION_SEARCH e cerca la query in un set di dati. Per creare un'attività disponibile per la ricerca, dichiara un'attività a tua scelta da filtrare in base all'intent ACTION_SEARCH:

<activity android:name=".SearchResultsActivity" ... >
    ...
    <intent-filter>
        <action android:name="android.intent.action.SEARCH" />
    </intent-filter>
    ...
</activity>

Nell'attività disponibile per la ricerca, gestisci l'intent ACTION_SEARCH controllandolo nel tuo metodo 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")
        }
    }
}

Ora, l'SearchView può accettare la query dell'utente e iniziare la tua attività ricercabile con l'intento ACTION_SEARCH.

Dopo aver ottenuto la query di ricerca, puoi passarla a ViewModel, dove puoi utilizzarla in altri livelli della tua architettura per recuperare i risultati di ricerca da visualizzare.