Como criar uma interface de pesquisa

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 de pesquisa podem entregar a consulta do usuário para uma atividade específica no app. Dessa forma, o usuário pode iniciar uma pesquisa a partir de qualquer atividade em que a caixa ou o widget de pesquisa estejam disponível, 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 guia 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

Figura 1. Captura de tela da caixa de pesquisa de um app.

Antes de começar, decida se a interface de pesquisa será implementada usando a caixa ou o widget de pesquisa. Os dois oferecem os mesmos recursos de pesquisa, mas de maneiras um pouco diferentes:

  • A caixa de pesquisa é um componente da IU controlado pelo sistema Android. Quando ativada pelo usuário, a caixa de pesquisa é exibida na parte superior da atividade, conforme mostrado na Figura 1.

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

    Observação: se quiser, você mesmo pode gerenciar todas as entradas do usuário no widget de pesquisa, usando vários métodos e listeners de callback. No entanto, este documento se concentra em como integrar o widget de pesquisa ao sistema para a implementação de pesquisa assistida. Se você mesmo quiser gerenciar todas as entradas do usuário, leia a documentação de referência para SearchView e as interfaces aninhadas correspondentes.

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

  • Uma configuração pesquisável

    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, mas aparece na parte superior da tela quando você chama onSearchRequested() (quando o usuário pressiona o botão "Pesquisar").

    • Ou um widget SearchView

      O uso do widget de pesquisa permite colocar a caixa de pesquisa em qualquer lugar da atividade. Em vez de colocá-lo no layout da atividade, use SearchView como uma visualização de ações na barra de apps.

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

Como criar uma configuração pesquisável

Para começar, você precisa de um arquivo XML chamado "configuração pesquisável". Ele configura alguns aspectos da IU 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/.

Observação: o sistema usa esse arquivo para instanciar um objeto SearchableInfo, mas você não pode criar esse objeto por conta própria durante a execução. É necessário declarar a configuração pesquisável em XML.

O arquivo de configuração pesquisável precisa incluir o elemento <searchable> como nó raiz e especificar um ou mais atributos. Exemplo:

    <?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 estará 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 ficará 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.

Dica: para manter a consistência com outros aplicativos para Android, formate a string de android:hint como “Pesquisar <conteúdo-ou-produto>”. Por exemplo, "Pesquisar músicas e artistas" ou "Pesquisar no YouTube".

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

Como criar uma atividade de pesquisa

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 é necessário declarar sua atividade de pesquisa no arquivo de manifesto do Android.

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

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

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 "android.app.searchable" e o atributo android:resource com uma referência ao arquivo de configuração pesquisável. Nesse exemplo, ele se refere ao arquivo res/xml/searchable.xml.

Observação: o <intent-filter> não precisa de uma <category> com o valor DEFAULT, que geralmente é visto em elementos <activity>. Isso porque o sistema entrega o intent ACTION_SEARCH explicitamente para a atividade de pesquisa, usando o nome do componente.

Como realizar uma pesquisa

Depois de declarar sua atividade de pesquisa no manifesto, uma pesquisa na atividade de pesquisa envolve três etapas:

  1. Receber a consulta
  2. Pesquisar seus dados
  3. Apresentar os resultados

Tradicionalmente, seus resultados da pesquisa são apresentados em uma ListView. Por isso, pode ser útil que sua atividade de pesquisa estenda ListActivity. Isso inclui o layout padrão com uma única ListView e fornece diversos métodos de conveniência para trabalhar com o ListView.

Receber a consulta

Quando o usuário realiza uma pesquisa na caixa de pesquisa ou no widget de pesquisa, o sistema inicia sua atividade de pesquisa e entrega um intent ACTION_SEARCH. O intent carrega a consulta de pesquisa no extra da string QUERY. É necessário verificar esse intent quando a atividade é iniciada e extrair 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. Nesse exemplo, a consulta é recuperada e transmitida para um método doMySearch() em que a operação de pesquisa é 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, mas este guia não mostra como armazenar seus dados e buscá-los. Armazenar e pesquisar seus dados é algo que você precisa considerar com cuidado de acordo com suas necessidades e o formato dos dados. Contudo, veja 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 ver informações sobre FTS3, e a classe SQLiteDatabase, para ver 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 uma roda de progresso até que a pesquisa retorne. Consulte android.net para ver uma referência de APIS da rede e Como criar uma caixa de diálogo com uma barra de progresso para ver informações sobre como exibir uma roda 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 Adapter. Dessa forma, você pode apresentar com facilidade todos os resultados da pesquisa em ListView. Caso seus dados sejam provenientes de uma consulta ao banco de dados SQLite, é possível aplicar os resultados a uma ListView usando um CursorAdapter. Caso seus dados sejam provenientes de outro tipo de formato, é possível criar 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 ListView, cada um dos dados é inserido como uma visualização individual na lista. Adapter é apenas uma interface. Por esse motivo, 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.

Recomendamos que sua atividade de pesquisa estenda ListActivity. Em seguida, você pode chamar setListAdapter(), transmitindo um Adapter que é vinculado aos seus dados. Isso injeta todos os resultados de pesquisa à ListView da atividade.

Para receber mais ajuda para apresentar seus resultados em uma lista, consulte a documentação de ListActivity.

Como usar a caixa de pesquisa

A caixa de pesquisa fornece uma caixa de pesquisa flutuante na parte superior da tela, com o ícone do app à esquerda. Ela pode oferecer sugestões de pesquisa à medida que o usuário digita e, quando o usuário realiza uma pesquisa, o sistema a envia para uma atividade de pesquisa que a executa. No entanto, se você estiver desenvolvendo seu app para dispositivos com o Android 3.0, considere a possibilidade de usar o widget de pesquisa (consulte a seção Como usar o widget de pesquisa).

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

Para ativar a caixa de pesquisa, é necessário indicar ao sistema qual atividade receberá consultas para realizar as pesquisas. Por exemplo, na seção anterior, Como criar uma atividade de pesquisa, foi criada uma atividade chamada SearchableActivity. Caso queira uma atividade separada (chamada OtherActivity) para mostrar a caixa de pesquisa e exibir pesquisas para SearchableActivity, é necessário declarar no manifesto que SearchableActivity é a atividade de pesquisa a ser usada na caixa de pesquisa OtherActivity.

Para declarar a atividade 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 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 a OtherActivity agora inclui um elemento <meta-data> para declarar qual atividade de pesquisa usar, a atividade ativou a caixa de pesquisa. Enquanto o usuário está 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.

Observação: por padrão, a própria atividade de pesquisa fornece a caixa de pesquisa. Portanto, não é necessário adicionar essa declaração a SearchableActivity.

Caso você queira que todas as atividades no app ofereçam a caixa de pesquisa, insira o elemento <meta-data> acima 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. Caso você tenha várias atividades de pesquisa, é possível substituir a atividade de pesquisa 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.

Como invocar a caixa de pesquisa

Embora alguns dispositivos forneçam um botão "Pesquisar" dedicado, o comportamento do botão pode variar entre dispositivos diferentes 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 IU que ative a caixa de pesquisa chamando onSearchRequested().

Por exemplo, adicione um botão "Pesquisar" no seu Menu de opções ou layout de IU que chama onSearchRequested(). Para manter consistência com o sistema Android e outros apps, coloque o ícone de pesquisa do Android no seu botão, disponível no Pacote de ícones para a barra de ações.

Observação: se seu app usa uma barra de apps, não use a caixa de pesquisa para sua interface de pesquisa. Em vez disso, use o widget de pesquisa como uma visualização que pode ser recolhida na barra do app.

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(DEFAULT_KEYS_SEARCH_LOCAL) durante o método onCreate() da sua atividade.

Impacto da caixa de pesquisa no ciclo de vida da atividade

A caixa de pesquisa é uma Dialog que flutua na parte superior da tela. Ela não causa nenhuma alteração na pilha de atividades. Portanto, quando a caixa de pesquisa aparece, nenhum método de ciclo de vida (por exemplo, onPause()) é chamado. Sua atividade só perde o foco de entrada, porque o foco passa para a 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 perdeu o foco de entrada para a caixa de pesquisa, a fim de que você possa fazer qualquer trabalho adequado para o evento (por exemplo, pausar um jogo). A menos que você esteja transmitindo dados de contexto de pesquisa (discutido abaixo), é necessário encerrar o método chamando a implementação de superclasse. Por exemplo:

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 pressionando o botão Voltar, a caixa 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 fechar com o setOnDismissListener() e/ou setOnCancelListener(). 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 fechou a caixa de pesquisa explicitamente. Por esse motivo, ele não é chamado quando uma pesquisa é realizada (nesse caso, a caixa desaparece naturalmente).

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() e assim por diante, conforme descrito no documento Atividades). No entanto, se a atividade atual for a atividade de pesquisa, acontecerá uma destas duas coisas:

  1. 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 existem duas instâncias da sua atividade de pesquisa na pilha de atividades. Portanto, ao pressionar o botão Voltar o usuário volta para a instância anterior da atividade de pesquisa, em vez de sair da atividade.
  2. Se você configurar android:launchMode como "singleTop", a atividade de pesquisa receberá o intent ACTION_SEARCH com uma chamada para onNewIntent(Intent), transmitindo o novo intent ACTION_SEARCH aqui. 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) {
            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) {
            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 foi reiniciada. Então, 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 é ideal, porque é provável que depois que uma pesquisa for realizada, o usuário fará outras pesquisas, e a criação de várias instâncias para a atividade de pesquisa gera uma experiência ruim. Portanto, recomendamos que a atividade de pesquisa seja definida no modo de inicialização "singleTop" no manifesto do app. Exemplo:

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

Como 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, caso você queira 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 Bundle de APP_DATA, 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ê adicionou. Você pode extrair os dados complementares do APP_DATA Bundle para refinar a pesquisa. Exemplo:

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

Atenção: nunca chame o método startSearch() de fora do método de callback onSearchRequested(). Para ativar a caixa de pesquisa na atividade, sempre chame onSearchRequested(). Caso contrário, onSearchRequested() não será chamado, e as personalizações (por exemplo, a adição de appData no exemplo acima) serão perdidas.

Como usar o widget de pesquisa

Figura 2. O widget SearchView como uma "visualização de ação" na barra de ações.

O widget SearchView está disponível no Android 3.0 e versões posteriores. Caso você esteja desenvolvendo seu app para o Android 3.0 e tenha decidido usar o widget de pesquisa, recomendamos que você insira o widget como uma visualização de ação na barra de apps, em vez de usar a caixa de pesquisa no layout da atividade. Por exemplo, a figura 2 mostra o widget de pesquisa 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 colocar o widget de pesquisa na Barra de ações não for uma opção para você, é possível colocá-lo no layout da sua atividade.

Observação: ao usar o widget como uma visualização de ação, ainda pode ser necessário oferecer compatibilidade com a caixa de pesquisa para casos em que o widget não cabe na barra de ações. Consulte a seção a seguir, Como usar o widget e a caixa de pesquisa.

Como configurar o widget de pesquisa

Depois de criar uma configuração pesquisável e uma atividade de pesquisa, conforme discutido acima, ative a pesquisa assistida para cada SearchView. Você pode fazer isso chamando setSearchableInfo() e transmitindo o objeto SearchableInfo que representa sua configuração pesquisável.

Você pode conseguir uma referência a 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():

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) // Do not 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); // Do not iconify the widget; expand it by default

        return true;
    }
    

Isso é tudo o que você precisa. Agora, o widget de pesquisa está configurado, e o sistema entregará consultas para sua atividade de pesquisa. Você também pode ativar sugestões de pesquisa para o widget.

Observação: caso queira, você mesmo pode processar todas as entradas do usuário com alguns métodos de callback e listeners de evento. Para ver mais informações, consulte a documentação de referência para SearchView e as interfaces aninhadas respectivas para os listeners de eventos adequados.

Para ver mais informações sobre as visualizações de ações na barra de ações, consulte Visualizações de açõ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 simplesmente 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).
Habilidade 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) e é expandido para exibir a caixa de pesquisa quando tocado pelo usuário. Conforme mostrado acima, é 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.

Como usar o widget e a caixa de pesquisa

Se você inserir o widget de pesquisa na barra de ações como uma visualização de ações e permitir que ele apareça na barra de ações "se houver espaço" (definindo android:showAsAction="ifRoom"), é possível que o widget de pesquisa não apareça como uma visualização de ações, mas o item de menu aparecerá no menu flutuante. Por exemplo, quando seu app é executado em uma tela menor, pode não haver espaço suficiente na barra de ações para exibir o widget de pesquisa junto com outros itens de ação ou elementos de navegação. Assim, o item será exibido 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 (o widget de pesquisa).

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

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

Como 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. Isso adiciona um botão de pesquisa por voz que inicia uma solicitação por voz. Quando o usuário terminar de falar, a consulta de pesquisa transcrita será enviada para sua atividade de pesquisa.

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, ao passo que 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 pesquisável para ver mais informações sobre os atributos disponíveis.

Observação: considere cuidadosamente se a pesquisa por voz é adequada para seu app. Todas as pesquisas realizadas com o botão de pesquisa por voz são enviadas imediatamente para sua atividade de pesquisa, sem que o usuário tenha chance de analisar a consulta transcrita. Teste o reconhecimento de voz o suficiente para garantir que ele entenda os tipos de consultas que o usuário pode enviar no seu app.

Como adicionar sugestão de pesquisa

Figura 3. Captura de tela de uma caixa de pesquisa com sugestões personalizadas.

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 simplesmente palavras que o usuário usou anteriormente como consultas de sugestões no app.

Consulte Como adicionar sugestões de consulta recentes.

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. A Figura 3 mostra um exemplo de sugestões personalizadas para um app de dicionário. O usuário pode selecionar uma sugestão para acessar instantaneamente a definição.

Veja Como adicionar sugestões personalizadas