Criar uma interface de pesquisa

Teste o jeito do Compose
O Jetpack Compose é o kit de ferramentas de UI recomendado para Android. Saiba como adicionar a funcionalidade de pesquisa no Compose.

Quando você estiver pronto para adicionar a funcionalidade de pesquisa ao seu app, o Android ajudará a implementar a interface do usuário com uma caixa de pesquisa que aparece na parte superior da janela de atividades ou um widget de pesquisa que pode ser inserido no layout. Tanto a caixa de pesquisa quanto o widget podem entregar a consulta do usuário para uma atividade específica no app. Dessa forma, o usuário pode iniciar uma pesquisa em qualquer atividade em que a caixa ou o widget de pesquisa estejam disponíveis, e o sistema inicia a atividade adequada para realizar a busca e apresentar resultados.

Outros recursos disponíveis para a caixa e o widget de pesquisa incluem:

  • Pesquisa por voz
  • Sugestões de pesquisa com base em consultas recentes
  • Sugestões de pesquisa que correspondem aos resultados reais nos dados do app

Este documento mostra como configurar seu app para oferecer uma interface de pesquisa assistida pelo sistema Android a fim de fornecer consultas de pesquisa, usando a caixa ou o widget de pesquisa.

Recursos relacionados:

Noções básicas

Antes de começar, decida se você quer implementar a interface de pesquisa usando a caixa ou o widget de pesquisa. Elas oferecem os mesmos recursos de pesquisa, mas de maneiras um pouco diferentes:

  • A caixa de pesquisa é um componente da interface do usuário controlado pelo sistema Android. Quando ativada pelo usuário, a caixa de pesquisa aparece na parte de cima da atividade.

    O sistema Android controla todos os eventos na caixa de pesquisa. Quando o usuário envia uma consulta, o sistema entrega a consulta à atividade que você especifica para processar pesquisas. A caixa de pesquisa também pode fornecer sugestões enquanto o usuário digita.

  • O widget de pesquisa é uma instância de SearchView que pode ser colocada em qualquer lugar do layout. Por padrão, o widget de pesquisa se comporta como um widget EditText padrão e não faz nada. Contudo, é possível configurá-lo para que o sistema do Android gerencie todos os eventos de entrada, envie consultas para a atividade apropriada e ofereça sugestões de pesquisa, exatamente como a caixa de pesquisa.

Quando o usuário realiza uma pesquisa na caixa ou no widget de pesquisa, o sistema cria um Intent e armazena a consulta. Em seguida, o sistema inicia a atividade que você declara para processar pesquisas (a "atividade de pesquisa") e fornece a ela o intent. Para configurar seu app para esse tipo de pesquisa assistida, você precisa do seguinte:

  • Uma configuração de pesquisa
    Um arquivo XML que inclua algumas configurações para a caixa ou o widget de pesquisa. Inclui configurações para recursos como pesquisa por voz, sugestão de pesquisa e texto de dica para a caixa de pesquisa.
  • Uma atividade de pesquisa
    A Activity que recebe a consulta de pesquisa, busca seus dados e exibe os resultados da pesquisa.
  • Uma interface de pesquisa, fornecida por:
    • A caixa de pesquisa
      Por padrão, a caixa de pesquisa fica oculta. Ele aparece na parte de cima da tela quando você chama onSearchRequested() quando o usuário toca no botão Pesquisar.
    • Um widget SearchView
      O uso do widget de pesquisa permite colocar a caixa de pesquisa em qualquer lugar da atividade, inclusive como uma visualização de ação na barra de apps.

O restante deste documento mostra como criar a configuração de pesquisa e a atividade pesquisável e como implementar uma interface de pesquisa com a caixa ou o widget de pesquisa.

Criar uma configuração pesquisável

Para começar, você precisa de um arquivo XML chamado configuração de pesquisa. Ele configura alguns aspectos da interface da caixa ou do widget de pesquisa e define a forma em que recursos como sugestões e pesquisa por voz se comportam. Tradicionalmente, esse arquivo é chamado de searchable.xml e precisa ser salvo no diretório do projeto res/xml/.

O arquivo de configuração de pesquisa precisa incluir o elemento <searchable> como nó raiz e especificar um ou mais atributos, conforme mostrado no exemplo a seguir:

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

O atributo android:label é o único atributo obrigatório. Ele aponta para um recurso de string, que precisa ser o nome do app. Esse rótulo não fica visível para o usuário até que você ative as sugestões de pesquisa para a caixa de pesquisa rápida. Nesse momento, o rótulo fica visível na lista de itens pesquisáveis nas configurações do sistema.

Embora não seja obrigatório, recomendamos que você sempre inclua o atributo android:hint, que fornece uma string de dica na caixa de pesquisa antes que o usuário insira uma consulta. A dica é importante porque oferece pistas importantes para o usuário sobre o que pode ser pesquisado.

O elemento <searchable> aceita vários outros atributos. No entanto, você não precisará da maioria dos atributos até adicionar recursos como sugestões de pesquisa e pesquisa por voz. Para informações detalhadas sobre o arquivo de configuração de pesquisa, consulte o documento de referência Configuração de pesquisa.

Criar uma atividade pesquisável

Uma atividade de pesquisa é a Activity no app que realiza pesquisas com base em uma string de consulta e apresenta os resultados da pesquisa.

Quando o usuário realiza uma pesquisa na caixa ou no widget de pesquisa, o sistema inicia sua atividade de pesquisa e entrega a consulta de pesquisa em um Intent com a ação ACTION_SEARCH. Sua atividade de pesquisa recupera a consulta da QUERY extra do intent e, em seguida, pesquisa seus dados e apresenta os resultados.

Como a caixa ou o widget de pesquisa podem ser incluídos em qualquer outra atividade no app, o sistema precisa saber qual atividade é a atividade de pesquisa para que ele possa entregar a consulta de pesquisa corretamente. Portanto, primeiro declare sua atividade de pesquisa no arquivo de manifesto do Android.

Declarar uma atividade de pesquisa

Caso Você ainda não tenha uma atividade de pesquisa, crie uma Activity que realizará as pesquisas e apresentará os resultados. Ainda não é necessário implementar a funcionalidade de pesquisa. Basta criar uma atividade que possa ser declarada no manifesto. No elemento <activity> do manifesto, faça o seguinte:

  1. Declare a atividade para aceitar o intent ACTION_SEARCH em um elemento <intent-filter>.
  2. Especifique a configuração de pesquisa a ser usada em um elemento <meta-data>.

Isso é mostrado neste exemplo:

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

O elemento <meta-data> precisa incluir o atributo android:name com um valor de "android.app.searchable" e o atributo android:resource com uma referência ao arquivo de configuração pesquisável. No exemplo anterior, ele se refere ao arquivo res/xml/searchable.xml.

Realizar uma pesquisa

Depois de declarar sua atividade de pesquisa no manifesto, siga este procedimento para fazer uma pesquisa nela:

  1. Receber a consulta.
  2. Pesquise seus dados.
  3. Apresente os resultados.

Receber a consulta

Quando o usuário realiza uma pesquisa na caixa ou no widget de pesquisa, o sistema inicia sua atividade de pesquisa e envia um intent ACTION_SEARCH. O intent carrega a consulta de pesquisa no extra da string QUERY. Verifique esse intent quando a atividade for iniciada e extraia a string. Por exemplo, veja como conseguir a consulta de pesquisa quando a atividade de pesquisa é iniciada:

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);
    }
}

A string QUERY sempre é incluída com o intent ACTION_SEARCH. No exemplo anterior, a consulta é recuperada e transmitida para um método doMySearch() local em que a operação de pesquisa real é realizada.

Pesquisar seus dados

O processo de armazenamento e pesquisa de dados é exclusivo para seu app. Você pode armazenar e pesquisar seus dados de várias maneiras, e este documento não mostra como. Considere como você armazena e pesquisa seus dados de acordo com suas necessidades e o formato dos dados. Confira algumas dicas que podem ser úteis:

  • Caso seus dados estejam armazenados em um banco de dados SQLite no dispositivo, realizar uma pesquisa de texto completo, usando FTS3, em vez de uma consulta LIKE, pode oferecer uma pesquisa mais robusta nos dados de texto e produzir resultados significativamente mais rápidos. Consulte sqlite.org (link em inglês) para informações sobre FTS3 e a classe SQLiteDatabase para informações sobre SQLite no Android.
  • Caso seus dados estejam armazenados on-line, o desempenho da pesquisa pode ser impedido pela conexão de dados do usuário. Recomendamos que você exiba um indicador de progresso até que a pesquisa retorne. Consulte android.net para ver uma referência de APIs de rede e ProgressBar para informações sobre como mostrar um indicador de progresso.

Apresentar os resultados

Independentemente de onde seus dados estejam e de como você os pesquisa, recomendamos que você retorne resultados de pesquisa para sua atividade de pesquisa com um Adapter. Dessa forma, você pode apresentar todos os resultados da pesquisa em um RecyclerView. Se os dados vierem de uma consulta ao banco de dados SQLite, é possível aplicar os resultados a uma RecyclerView usando um CursorAdapter. Se os dados vierem em um formato diferente, crie uma extensão de BaseAdapter.

Um Adapter vincula cada item de um conjunto de dados a um objeto View. Quando o Adapter é aplicado a uma RecyclerView, cada dado é inserido como uma visualização individual na lista. Adapter é apenas uma interface. Por isso, são necessárias implementações como CursorAdapter (para vincular dados de um Cursor). Se nenhuma das implementações já existentes funcionar para seus dados, é possível implementar uma das suas a partir do BaseAdapter.

Usar a caixa de pesquisa

A caixa de pesquisa fornece uma caixa de pesquisa flutuante na parte de cima da tela, com o ícone do app à esquerda. Ela pode oferecer sugestões de pesquisa à medida que o usuário digita. Quando o usuário realiza uma pesquisa, o sistema envia a consulta de pesquisa para uma atividade de pesquisa que a executa.

Por padrão, a caixa de pesquisa fica escondida até que o usuário a ative. Seu app pode ativar a caixa de pesquisa chamando onSearchRequested(). No entanto, esse método não funciona até que você ative a caixa de pesquisa para a atividade.

Para ativar a caixa de pesquisa, indique ao sistema qual atividade de pesquisa precisa receber consultas da caixa. Por exemplo, na seção anterior sobre como criar uma atividade de pesquisa, uma atividade de pesquisa chamada SearchableActivity foi criada. Se você quiser uma atividade separada, como uma chamada OtherActivity, para mostrar a caixa de pesquisa e exibir pesquisas para SearchableActivity, declare no manifesto que SearchableActivity é a atividade de pesquisa a ser usada na caixa de pesquisa em OtherActivity.

Para declarar a atividade de pesquisa para uma caixa de pesquisa, adicione um elemento <meta-data> no elemento <activity> da respectiva atividade. O elemento <meta-data> precisa incluir o atributo android:value que especifica o nome da classe da atividade de pesquisa e o atributo android:name com um valor de "android.app.default_searchable".

Por exemplo, veja a declaração para uma atividade de pesquisa, SearchableActivity, e outra atividade, OtherActivity, que usa SearchableActivity para realizar pesquisas executadas a partir da respectiva caixa:

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

Como OtherActivity agora inclui um elemento <meta-data> para declarar qual atividade de pesquisa usar, a atividade ativa a caixa de pesquisa. Embora o usuário esteja nessa atividade, o método onSearchRequested() ativa a caixa de pesquisa. Quando o usuário realiza a pesquisa, o sistema inicia SearchableActivity e entrega o intent ACTION_SEARCH.

Se você quiser que todas as atividades no app ofereçam a caixa de pesquisa, insira o elemento <meta-data> anterior como um filho do elemento <application>, em vez de cada <activity>. Dessa forma, todas as atividades herdam o valor, oferecem a caixa de pesquisa e enviam as pesquisas para a mesma atividade. Se você tiver várias atividades de pesquisa, é possível substituir a atividade padrão colocando uma declaração <meta-data> diferente nas atividades individuais.

Com a caixa de pesquisa ativada para suas atividades, seu app estará pronto para realizar pesquisas.

Invocar a caixa de pesquisa

Embora alguns dispositivos forneçam um botão de pesquisa dedicado, o comportamento do botão pode variar entre dispositivos, e muitos não fornecem um botão de pesquisa. Portanto, ao usar a caixa de pesquisa, é necessário fornecer um botão de pesquisa na UI que ative a caixa chamando onSearchRequested().

Por exemplo, adicione um botão de pesquisa no seu menu de opções ou layout de IU que chama onSearchRequested().

Você também pode ativar a funcionalidade "type-to-search", que ativa a caixa de pesquisa quando o usuário começa a digitar no teclado. As teclas pressionadas são inseridas na caixa de pesquisa. Você pode ativar a "type-to-search" na atividade chamando setDefaultKeyMode ou DEFAULT_KEYS_SEARCH_LOCAL durante o método onCreate() da atividade.

Impacto da caixa de pesquisa no ciclo de vida da atividade

A caixa de pesquisa é uma Dialog que flutua na parte de cima da tela. Ela não causa nenhuma mudança na pilha de atividades. Portanto, quando a caixa de pesquisa aparece, nenhum método de ciclo de vida, como onPause(), é chamado. Sua atividade perde o foco de entrada, porque ele é dado à caixa de pesquisa.

Se você quiser ser notificado quando a caixa de pesquisa estiver ativada, substitua o método onSearchRequested(). Quando o sistema chama esse método, é uma indicação de que sua atividade perde o foco de entrada para a caixa de pesquisa. Assim, você pode fazer qualquer trabalho adequado para o evento, como pausar um jogo. A menos que você esteja transmitindo dados de contexto de pesquisa, discutidos em outra seção deste documento, encerre o método chamando a implementação de superclasse:

Kotlin

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

Java

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

Se o usuário cancelar a pesquisa tocando no botão "Voltar", a caixa de diálogo de pesquisa será fechada, e a atividade voltará a ter o foco de entrada. É possível se registrar para receber uma notificação quando a caixa de pesquisa for fechada com setOnDismissListener(), setOnCancelListener() ou ambos. Só é necessário registrar o OnDismissListener, porque ele é chamado todas as vezes que a caixa de pesquisa é fechada. O OnCancelListener só se refere a eventos em que o usuário fecha a caixa de pesquisa explicitamente. Por isso, ele não é chamado quando uma pesquisa é realizada. Quando a pesquisa é executada, a caixa de diálogo desaparece automaticamente.

Se a atividade atual não for a atividade de pesquisa, os eventos normais do ciclo de vida da atividade serão acionados quando o usuário realizar uma pesquisa. A atividade atual recebe onPause(), conforme descrito em Introdução às atividades. No entanto, se a atividade atual for a atividade de pesquisa, acontecerá uma destas duas coisas:

  • Por padrão, a atividade de pesquisa recebe o intent ACTION_SEARCH com uma chamada para onCreate(), e uma nova instância da atividade é colocada no topo da pilha de atividades. Agora há duas instâncias da sua atividade de pesquisa na pilha de atividades. Portanto, ao tocar no botão "Voltar", você volta para a instância anterior da atividade de pesquisa, em vez de sair dela.
  • Se você definir android:launchMode como "singleTop", a atividade de pesquisa vai receber o intent ACTION_SEARCH com uma chamada para onNewIntent(Intent), transmitindo o novo intent ACTION_SEARCH. Por exemplo, veja como processar esse caso, em que o modo de inicialização da atividade de pesquisa é "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);
        }
    }

    Em comparação com o código de exemplo na seção sobre como realizar uma pesquisa, todo o código para processar o intent de pesquisa agora está no método handleIntent() para que ambos onCreate() e onNewIntent() possam executá-lo.

    Quando o sistema chama onNewIntent(Intent), a atividade não é reiniciada. Portanto, o método getIntent() retorna o mesmo intent recebido com onCreate(). É por isso que você precisa chamar setIntent(Intent) no onNewIntent(Intent), para que o intent salvo pela atividade seja atualizado caso você chame getIntent() no futuro.

O segundo cenário, usando o modo de inicialização "singleTop", geralmente é preferível porque, depois de uma pesquisa, o usuário pode fazer outras, e você não quer que seu app crie várias instâncias da atividade de pesquisa. Recomendamos que você defina a atividade de pesquisa no modo de inicialização "singleTop" no manifesto do app, conforme mostrado no exemplo a seguir:

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

Transmitir dados de contexto de pesquisa

Em alguns casos, é possível fazer os refinamentos necessários na consulta de pesquisa dentro da atividade de pesquisa para cada pesquisa feita. No entanto, se você quiser refinar seus critérios de pesquisa com base na atividade em que o usuário está realizando uma pesquisa, forneça dados complementares no intent que o sistema envia para sua atividade de pesquisa. Você pode transmitir os dados complementares no APP_DATA Bundle, que está incluído no intent ACTION_SEARCH.

Para transmitir esse tipo de dados para sua atividade de pesquisa, substitua o método onSearchRequested() para a atividade em que o usuário pode realizar uma pesquisa, crie um Bundle com os dados complementares e chame startSearch() para ativar a caixa de pesquisa. Exemplo:

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

Retornar "true" indica que você processou corretamente esse evento de callback e chamou startSearch() para ativar a caixa de pesquisa. Depois que o usuário envia uma consulta, ela é entregue à sua atividade de pesquisa com os dados que você adiciona. Você pode extrair os dados extras do APP_DATA Bundle para refinar a pesquisa, conforme mostrado no exemplo a seguir:

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);
}

Usar o widget de pesquisa

Imagem mostrando uma visualização de pesquisa na barra de apps superior

Figura 1. O widget SearchView como uma visualização de ação na barra de apps.

O widget oferece a mesma funcionalidade que a caixa de pesquisa. Ele inicia a atividade adequada quando o usuário realiza uma pesquisa e pode oferecer sugestões de pesquisa e realizar a pesquisa por voz. Se não for possível colocar o widget de pesquisa na barra de apps, coloque-o em algum lugar no layout da atividade.

Configurar o widget de pesquisa

Depois de criar uma configuração de pesquisa e uma atividade de pesquisa, ative a pesquisa assistida para cada SearchView chamando setSearchableInfo() e transmitindo o objeto SearchableInfo que representa sua configuração de pesquisa.

Você pode conseguir uma referência ao SearchableInfo chamando getSearchableInfo() em SearchManager.

Por exemplo, se você estiver usando uma SearchView como uma visualização de ações na barra de apps, ative o widget durante o callback de onCreateOptionsMenu(), conforme mostrado no exemplo a seguir:

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

Agora, o widget de pesquisa está configurado, e o sistema entrega consultas de pesquisa para sua atividade de pesquisa. Você também pode ativar as sugestões de pesquisa para o widget.

Para mais informações sobre as visualizações de ações na barra de apps, consulte Usar visualizações e provedores de ações.

Outros recursos do widget de pesquisa

O widget SearchView oferece alguns outros recursos que você pode querer:

Um botão de envio
Por padrão, não há um botão para enviar uma consulta de pesquisa. Por esse motivo, o usuário precisa pressionar a tecla Enter no teclado para iniciar uma pesquisa. Você pode adicionar um botão "enviar" chamando setSubmitButtonEnabled(true).
Refinamento de consulta para sugestões de pesquisa
Quando você ativa as sugestões de pesquisa, normalmente espera-se que o usuário selecione uma sugestão, mas é possível que ele queira refinar a consulta de pesquisa sugerida. Você pode adicionar um botão ao lado de cada sugestão que a insira na caixa de pesquisa para que o usuário possa realizar o refinamento, chamando setQueryRefinementEnabled(true).
A capacidade de alternar a visibilidade da caixa de pesquisa
Por padrão, o widget de pesquisa é colocado em um ícone, ou seja, é representado apenas por um ícone de pesquisa (uma lupa). Ele é expandido para mostrar a caixa de pesquisa quando o usuário toca no ícone. Conforme mostrado no exemplo anterior, é possível exibir a caixa de pesquisa por padrão chamando setIconifiedByDefault(false). Também é possível alternar a aparência do widget de pesquisa chamando setIconified().

Várias outras APIs na classe SearchView permitem personalizar o widget de pesquisa. Contudo, a maior parte dessas APIs é usada somente quando você processa todas as entradas do usuário, em vez de usar o sistema Android para entregar consultas de pesquisa e exibir sugestões de pesquisa.

Usar o widget e a caixa de pesquisa

Se você inserir o widget de pesquisa na barra de apps como uma visualização de ação e permitir que ele apareça na barra de apps se houver espaço (definindo android:showAsAction="ifRoom"), o widget de pesquisa poderá não aparecer como uma visualização de ação. Em vez disso, um item de menu pode aparecer no menu flutuante. Por exemplo, quando seu app é executado em uma tela menor, pode não haver espaço suficiente na barra de apps para mostrar o widget de pesquisa junto com outros itens de ação ou elementos de navegação. Assim, o item de menu aparece no menu flutuante. Quando colocado no menu flutuante, o item funciona como um item de menu comum e não exibe a visualização de ações, ou seja, o widget de pesquisa.

Para processar essa situação, o item de menu em que o widget de pesquisa foi anexado precisa ativar a caixa de pesquisa quando o usuário o seleciona no menu flutuante. Para fazer isso, implemente onOptionsItemSelected() para processar o item de menu "Pesquisar" e abra a caixa de pesquisa chamando onSearchRequested().

Para mais informações sobre como os itens na barra de apps funcionam e como processar essa situação, consulte Adicionar a barra de apps.

Adicionar a pesquisa por voz

Você pode adicionar a funcionalidade de pesquisa por voz à caixa ou ao widget de pesquisa adicionando o atributo android:voiceSearchMode à sua configuração pesquisável. Isso adiciona um botão de pesquisa por voz que inicia uma solicitação por voz. Quando o usuário termina de falar, a consulta de pesquisa transcrita é enviada para sua atividade de pesquisa.

Isso é mostrado neste exemplo:

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

O valor showVoiceSearchButton é obrigatório para ativar a pesquisa por voz. O segundo valor, launchRecognizer, especifica que o botão de pesquisa por voz precisa iniciar um reconhecedor que retorna o texto transcrito para a atividade de pesquisa.

Você pode fornecer atributos complementares para especificar o comportamento da pesquisa por voz, por exemplo, o idioma esperado e o número máximo de resultados a serem retornados. Consulte a referência Configuração de pesquisa para mais informações sobre os atributos disponíveis.

Adicionar sugestões de pesquisa

Tanto a caixa quanto o widget de pesquisa podem fornecer sugestões de pesquisa à medida que o usuário digita, com a ajuda do sistema Android. O sistema gerencia a lista de sugestões e processa o evento quando o usuário seleciona uma sugestão.

Você pode fornecer dois tipos de sugestões de pesquisa:

Sugestões de pesquisa de consulta recentes
Essas sugestões são palavras que o usuário usou anteriormente como consultas de pesquisa no app. Consulte Adicionar sugestões de pesquisa personalizadas para mais informações.
Sugestões de pesquisa personalizadas
São sugestões de pesquisa que você fornece a partir da sua fonte de dados para ajudar os usuários a selecionar imediatamente a ortografia ou o item correto que está sendo procurado. Consulte Adicionar sugestões de pesquisa personalizadas para mais informações.