Criar uma interface de pesquisa

Quando estiver tudo pronto para adicionar a funcionalidade de pesquisa ao app, o Android vai ajudar você a implementar a interface do usuário com uma caixa de diálogo de pesquisa que aparece na parte de cima da janela de atividades ou um widget de pesquisa que pode ser inserido no layout. A caixa de pesquisa e o widget podem entregar a consulta de pesquisa do usuário a uma atividade específica no app. Dessa forma, o usuário pode iniciar uma pesquisa de qualquer atividade em que a caixa ou o widget de pesquisa estejam disponíveis, e o sistema inicia a atividade adequada para realizar a pesquisa e apresentar os 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 fornecer uma interface de pesquisa com a ajuda do sistema Android para 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 de diálogo ou o widget de pesquisa. Elas oferecem os mesmos recursos de pesquisa, mas de maneiras um pouco diferentes:

  • A caixa de diálogo de pesquisa é um componente de IU controlado pelo sistema Android. Quando ativada pelo usuário, a caixa de pesquisa é mostrada 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 a entrega à atividade especificada para processar as pesquisas. A caixa de diálogo também pode oferecer sugestões de pesquisa 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 EditText padrão e não faz nada, mas você pode configurá-lo para que o sistema Android processe todos os eventos de entrada, envie consultas para a atividade apropriada e forneça sugestões de pesquisa, assim como a caixa de diálogo de pesquisa.

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

  • Uma configuração de pesquisa
    Um arquivo XML que define algumas configurações para a caixa de diálogo ou o widget de pesquisa. Ele inclui configurações para recursos como pesquisa por voz, sugestão de pesquisa e texto de dica para a caixa de pesquisa.
  • Uma atividade pesquisável
    O Activity que recebe a consulta de pesquisa, pesquisa seus dados e exibe os resultados da pesquisa.
  • Uma interface de pesquisa, fornecida por uma das seguintes opções:
    • Caixa de diálogo de pesquisa
      Por padrão, a caixa de diálogo de pesquisa fica oculta. Ela aparece na parte de cima da tela quando você chama onSearchRequested() quando o usuário toca no botão Search.
    • 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ções na barra de apps.

O restante deste documento mostra como criar a configuração e a atividade de pesquisa, além de implementar uma interface de pesquisa com a caixa ou o widget de pesquisa.

Criar uma configuração pesquisável

Primeiro, você precisa de um arquivo XML chamado configuração de pesquisa. Ele configura determinados aspectos da interface da caixa de diálogo ou do widget de pesquisa e define como recursos como sugestões e pesquisa por voz se comportam. Esse arquivo costuma ser 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 abaixo:

<?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. Ela 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 os usuários insiram uma consulta. A dica é importante porque fornece pistas importantes para os usuários sobre o que eles podem pesquisar.

O elemento <searchable> aceita vários outros atributos. No entanto, você não precisa 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 pesquisável é a Activity do app que realiza pesquisas com base em uma string de consulta e apresenta os resultados.

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 em um Intent com a ação ACTION_SEARCH. A atividade de pesquisa recupera a consulta do extra QUERY da intent e, em seguida, pesquisa seus dados e apresenta os resultados.

Como você pode incluir a caixa de diálogo ou o widget de pesquisa em qualquer outra atividade no app, o sistema precisa saber qual é a atividade de pesquisa para que ele possa fornecer corretamente a consulta de pesquisa. Portanto, primeiro declare sua atividade de pesquisa no arquivo de manifesto do Android.

Declarar uma atividade pesquisável

Caso ainda não tenha uma, crie uma Activity que realize pesquisas e apresente resultados. Você ainda não precisa 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 a 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 a atividade de pesquisa no manifesto, siga este procedimento para realizar uma pesquisa nela:

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

Receber a consulta

Quando um usuário realiza uma pesquisa na caixa ou no widget de pesquisa, o sistema inicia sua atividade de pesquisa e envia uma intent ACTION_SEARCH. Essa intent carrega a consulta de pesquisa no extra de 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 na 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 do seu app. É possível armazenar e pesquisar seus dados de várias maneiras, e este documento não mostra como fazer isso. Considere como você armazena e pesquisa os dados de acordo com suas necessidades e o formato dos dados. Veja algumas dicas que podem ser aplicadas:

  • Se os dados estiverem armazenados em um banco de dados SQLite no dispositivo, realizar uma pesquisa de texto completo (usando FTS3, em vez de uma consulta LIKE) pode fornecer uma pesquisa mais robusta em dados de texto e pode produzir resultados significativamente mais rápido. Consulte sqlite.org para informações sobre FTS3 e a classe SQLiteDatabase para informações sobre SQLite no Android.
  • Se os dados estiverem armazenados on-line, o desempenho percebido da pesquisa poderá ser inibido pela conexão de dados do usuário. Você pode mostrar um indicador de progresso até que a pesquisa retorne. Consulte android.net para uma referência de APIs de rede e ProgressBar para informações sobre como exibir um indicador de progresso.

Apresentar os resultados

Independentemente de onde seus dados estejam e como você os pesquisa, recomendamos que você retorne os resultados da pesquisa para sua atividade de pesquisa com um Adapter. Dessa forma, você pode apresentar todos os resultados da pesquisa em uma RecyclerView. Se os dados são provenientes de uma consulta no banco de dados SQLite, é possível aplicar os resultados a uma RecyclerView usando um CursorAdapter. Se os dados tiverem 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 um RecyclerView, cada dado é inserido como uma visualização individual na lista. Adapter é apenas uma interface. Portanto, são necessárias implementações como CursorAdapter, para vincular dados de um Cursor. Se nenhuma das implementações existentes funcionar para seus dados, você pode implementar uma das implementações existentes a partir de BaseAdapter.

Usar a caixa de pesquisa

A caixa de pesquisa oferece uma caixa de pesquisa flutuante na parte de cima da tela, com o ícone do app à esquerda. A caixa de pesquisa pode fornecer sugestões de pesquisa conforme o usuário digita. Quando o usuário realiza uma pesquisa, o sistema envia a consulta para uma atividade pesquisável que realiza a pesquisa.

Por padrão, a caixa de pesquisa fica sempre oculta até ser ativada pelo usuário. 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 permitir que a caixa de pesquisa realize pesquisas, indique ao sistema qual atividade pesquisável precisa receber consultas da caixa de pesquisa. Por exemplo, na seção anterior, sobre como criar uma atividade pesquisável, uma atividade pesquisável chamada SearchableActivity foi criada. Se você quiser que uma atividade separada, como uma chamada OtherActivity, mostre a caixa de pesquisa e entregue pesquisas para SearchableActivity, declare no manifesto que SearchableActivity é a atividade de pesquisa a ser usada para a caixa de pesquisa em OtherActivity.

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

Por exemplo, esta é a declaração de uma atividade de pesquisa, SearchableActivity, e de outra, OtherActivity, que usa SearchableActivity para realizar pesquisas executadas na caixa de diálogo de pesquisa:

<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 para as pesquisas, a atividade ativa a caixa de diálogo de pesquisa. Embora o usuário esteja nessa atividade, o método onSearchRequested() ativa a caixa de pesquisa. Quando o usuário executa a pesquisa, o sistema inicia SearchableActivity e envia a intent ACTION_SEARCH.

Caso queira que todas as atividades do app ofereçam a caixa de pesquisa, insira o elemento <meta-data> anterior como filho do elemento <application>, em vez de cada <activity>. Dessa forma, cada atividade herda o valor, disponibiliza a caixa de diálogo de pesquisa e direciona as pesquisas para a mesma atividade pesquisável. Se você tem várias atividades de pesquisa, é possível substituir a atividade de pesquisa padrão colocando uma declaração <meta-data> diferente dentro de atividades individuais.

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

Invocar a caixa de diálogo de pesquisa

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

Por exemplo, adicione um botão de pesquisa ao menu de opções ou ao layout da IU que chame onSearchRequested().

Você também pode ativar a funcionalidade "digite para pesquisar", que ativa a caixa de diálogo de pesquisa quando o usuário começa a digitar no teclado. As teclas pressionadas são inseridas na caixa de diálogo 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 é um Dialog que flutua na parte superior da tela. Ele 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 o foco de entrada é fornecido à caixa de pesquisa.

Se você quiser receber uma notificação quando a caixa de pesquisa estiver ativada, modifique o método onSearchRequested(). Quando o sistema chama esse método, isso é uma indicação de que sua atividade perde o foco de entrada para a caixa de diálogo de pesquisa, o que possibilita que você faça 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 da 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 vai recuperar o foco de entrada. Você pode se registrar para receber uma notificação quando a caixa de pesquisa for fechada com setOnDismissListener(), setOnCancelListener() ou ambos. Você só precisa registrar o OnDismissListener, porque ele é chamado sempre que a caixa de pesquisa é fechada. O OnCancelListener só se refere a eventos em que o usuário sai explicitamente da caixa de diálogo de pesquisa. Portanto, ele não é chamado quando uma pesquisa é executada. Quando a pesquisa é executada, a caixa de diálogo desaparece automaticamente.

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

  • Por padrão, a atividade pesquisável recebe o intent ACTION_SEARCH com uma chamada para onCreate(), e uma nova instância da atividade é trazida para o topo da pilha de atividades. Agora, há duas instâncias da sua atividade de pesquisa na pilha de atividades. Portanto, tocar no botão "Voltar" leva você de volta à instância anterior da atividade de pesquisa, em vez de sair dela.
  • Se você definir android:launchMode como "singleTop", a atividade pesquisável vai receber o intent ACTION_SEARCH com uma chamada para onNewIntent(Intent), transmitindo a nova intent ACTION_SEARCH. Por exemplo, veja como lidar com 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 a intent de pesquisa agora está no método handleIntent(), para que onCreate() e onNewIntent() possam executá-lo.

    Quando o sistema chama onNewIntent(Intent), a atividade não é reiniciada. Portanto, o método getIntent() retorna a mesma intent recebida com onCreate(). É por isso que é necessário chamar setIntent(Intent) dentro de onNewIntent(Intent): para que a intent salva pela atividade seja atualizada caso você chame getIntent() no futuro.

O segundo cenário, usando o modo de inicialização "singleTop", geralmente é recomendado porque, após a conclusão de uma pesquisa, o usuário pode realizar outras pesquisas, e você não quer que seu app crie várias instâncias da atividade pesquisável. Recomendamos que você defina sua atividade de pesquisa para o modo de inicialização "singleTop" no manifesto do app, conforme mostrado no exemplo abaixo:

<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 os critérios de pesquisa com base na atividade em que o usuário está realizando uma pesquisa, forneça mais dados na intent que o sistema envia para sua atividade pesquisável. Você pode transmitir os dados extras no Bundle APP_DATA, que está incluído na intent ACTION_SEARCH.

Para transmitir esse tipo de dados à 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 adicionais e chame startSearch() para ativar a caixa de diálogo de pesquisa. Por 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ê processa esse evento de callback e chama startSearch() para ativar a caixa de diálogo de pesquisa. Depois que o usuário envia uma consulta, ela é entregue à sua atividade de pesquisa com os dados que você adiciona. É possível extrair os dados extras do Bundle APP_DATA 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 da Pesquisa

Imagem que mostra uma visualização de pesquisa na barra superior do app

Figura 1. O widget SearchView como 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 fornecer 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, você poderá colocá-lo 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 a configuração pesquisável.

Para conseguir uma referência ao SearchableInfo, chame 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 onCreateOptionsMenu(), como 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;
}

O widget de pesquisa agora está configurado, e o sistema entrega consultas de pesquisa à sua atividade de pesquisa. Também é possível ativar sugestões de pesquisa para o widget.

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

Outros recursos do widget de pesquisa

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

Um botão de envio
Por padrão, não há um botão para enviar uma consulta de pesquisa. Portanto, o usuário precisa pressionar a tecla Return para iniciar uma pesquisa. Para adicionar um botão "enviar", chame setSubmitButtonEnabled(true).
Refinamento de consulta para sugestões de pesquisa
Quando você ativa as sugestões de pesquisa, normalmente espera-se que os usuários selecionem uma sugestão, mas eles também podem querer refinar a consulta de pesquisa sugerida. Você pode adicionar um botão ao lado de cada sugestão que a insere na caixa de pesquisa para refinamento pelo usuário chamando setQueryRefinementEnabled(true).
A capacidade de alternar a visibilidade da caixa de pesquisa
Por padrão, o widget de pesquisa fica em um ícone, ou seja, ele é representado apenas por um ícone de pesquisa, que é uma lupa. Ela se expande para mostrar a caixa de pesquisa quando o usuário toca no ícone. Conforme mostrado no exemplo anterior, é possível mostrar a caixa de pesquisa por padrão chamando setIconifiedByDefault(false). Também é possível alternar a aparência do widget de pesquisa chamando setIconified().

Existem várias outras APIs na classe SearchView que permitem personalizar o widget de pesquisa. No entanto, a maioria delas é usada apenas quando você processa todas as entradas do usuário, em vez de usar o sistema Android para entregar consultas e mostrar sugestões de pesquisa.

Usar o widget e a caixa de diálogo

Se você inserir o widget de pesquisa na barra de apps como uma visualização de ações e ativá-lo na barra de apps se houver espaço, definindo android:showAsAction="ifRoom", o widget pode não aparecer como uma visualização de ações. Em vez disso, um item de menu pode aparecer no menu flutuante. Por exemplo, quando o app é executado em uma tela menor, pode não haver espaço suficiente na barra de apps para mostrar o widget de pesquisa com outros itens de ação ou elementos de navegação. Portanto, 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 mostra a visualização de ações, ou seja, o widget de pesquisa.

Para lidar com essa situação, o item de menu ao qual você anexa o widget de pesquisa precisa ativar a caixa de diálogo de pesquisa quando o usuário o seleciona no menu flutuante. Para que isso aconteça, implemente onOptionsItemSelected() para processar o item de menu "Pesquisar" e abra a caixa de diálogo de pesquisa chamando onSearchRequested().

Para saber mais sobre como os itens na barra de apps funcionam e como lidar com essa situação, consulte Adicionar a barra de apps.

Adicionar pesquisa por voz

Você pode adicionar a funcionalidade de pesquisa por voz à caixa ou ao widget de pesquisa adicionando o atributo android:voiceSearchMode à 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 pesquisável.

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 é necessá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 pesquisável.

Você pode fornecer atributos adicionais para especificar o comportamento da pesquisa por voz, como 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 seu 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 da sua própria fonte de dados para ajudar os usuários a selecionar imediatamente a ortografia ou o item correto que eles estão procurando. Consulte Adicionar sugestões de pesquisa personalizadas para mais informações.