DEV Community

Luiz Franco
Luiz Franco

Posted on

Implementando uma Toolbar no Android Studio com Kotlin

A Toolbar é um dos elementos de design mais importantes do Android, tendo o objetivo de mostrar ao usuário, de forma facilitada, ações e funcionalidades básicas do aplicativo, como um menu e um mecanismo de busca.

Neste tutorial, vamos construir um aplicativo simples e implementar uma Toolbar básica e funcional do zero, esclarecendo algumas dúvidas comuns que podem surgir quando se está iniciando no desenvolvimento Android (como, por exemplo, qual a diferença entre uma action bar e uma Toolbar) e seguindo as melhores práticas recomendadas pelo Google e pelas guidelines do Material Design.

Ao final, você deve ter um aplicativo semelhante a esse, com uma Toolbar com um botão de busca e um botão que abre um menu overflow com outras funcionalidades do aplicativo:

alt text

Na segunda tela, há ainda uma seta para retornar à tela principal, conhecida como up button:

alt text

Pré-requisitos: Conhecimentos básicos de Android Studio e Kotlin
SDK mínimo utilizado no projeto: API 23: Android 6.0 (Marshmallow)
Versão do Android Studio utilizada no projeto: 4.1.1

Você pode conferir o código-fonte completo deste projeto neste repositório do Github.

1. Criando o projeto

Para começar, vamos criar um projeto básico com uma Empty Activity. Vou nomear o meu aplicativo de Tutorial Toolbar. Para este projeto, iremos utilizar a linguagem Kotlin e a versão mínima do Android será a 6.0 (API 23).

creatingproject

2. Desativando a action bar

Por padrão, a nossa Empty Activity já possui uma action bar. A Toolbar foi introduzida apenas no Android 5.0 (API 21). As boas práticas do Google recomendam, para o desenvolvimento de aplicativos modernos, o uso de uma Toolbar no lugar da action bar padrão. Ela nada mais é do que uma generalização mais flexível e moderna da action bar, podendo ser inserida em qualquer lugar do aplicativo e possuindo suporte a um maior conjunto de funcionalidades - além de poder ser configurada, com poucas linhas de código, para incorporar todas as funcionalidades e métodos de uma action bar padrão. E é exatamente o que vamos fazer neste projeto.

O primeiro arquivo a ser alterado será o themes.xml. No modo de visualização Android (e não Project), ele está na pasta app/res/values/themes. Se você estiver usando outra versão do Android Studio, é possível que ele esteja localizado em outro lugar. Seu objetivo é mudar o tema do aplicativo.

themes

O tema default, no Android Studio 4.1.1, é Theme.MaterialComponents.DayNight.DarkActionBar. Você vai substitui-lo pela variação NoActionBar. Seu código deverá ficar assim:

<resources xmlns:tools="http://schemas.android.com/tools">
    <style name="Theme.TutorialToolbar" parent="Theme.MaterialComponents.DayNight.NoActionBar">
...
    </style>
</resources>
Enter fullscreen mode Exit fullscreen mode

3. Criando a Toolbar

Agora que a action bar foi desativada, vamos criar a nossa Toolbar. Ela será criada como um arquivo xml dentro da pasta app/res/layout. Também poderíamos criá-la como um widget, dentro do arquivo de layout da nossa Main Activity. Mas, desta forma, precisaríamos copiar ou reescrever o código de layout da Toolbar em cada Activity. Criando um arquivo separado, basta incluí-la com a tag include, como vamos ver posteriormente.

Para criá-la, basta ir com o botão direito em layout e selecionar New > Layout Resource File. Vamos chamar o nosso arquivo simplesmente de toolbar. Em Root element, vamos substituir o que quer que esteja escrito por androidx.appcompat.widget.Toolbar e clicar em Ok.

newtoolbar

Em seguida, vamos nomeá-la com o id toolbar, para podermos identificá-la em nossa Main Activity. Para a Toolbar ocupar toda a largura da tela, mas ficar posicionada apenas como uma barra superior, sua largura será definida como match_parent e sua altura como wrap_content. Por hora, iremos apenas diferenciá-la da cor do fundo do aplicativo alterando seu background para a cor primária padrão do aplicativo. O código da sua Toolbar deverá estar assim por enquanto:

<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="?attr/colorPrimary"
    >

</androidx.appcompat.widget.Toolbar>
Enter fullscreen mode Exit fullscreen mode

4. Implementando a Toolbar na Main Activity

Agora que temos o nosso primeiro protótipo da Toolbar, vamos implementá-la em nossa Main Activity e programá-la para incorporar todos os métodos e funções de uma action bar, através do método setSupportActionBar(). Em Kotlin, temos duas maneiras de fazer isso:

  • Criando uma variável para receber a Toolbar, atribuindo a ela a toolbar criada dentro da pasta de Resources e, em seguida, a usando como parâmetro para chamar o método.
val toolbar = findViewById<Toolbar>(R.id.toolbar)
setSupportActionBar(toolbar)
Enter fullscreen mode Exit fullscreen mode
  • Utilizando uma sintaxe reduzida e chamando o método referenciando diretamente o arquivo da toolbar, sem necessidade de criar uma variável.
setSupportActionBar(findViewById(R.id.toolbar))
Enter fullscreen mode Exit fullscreen mode

Neste projeto, vamos utilizar a primeira maneira, porque iremos chamar a variável para manipular um detalhe da Toolbar com mais facilidade no futuro.

Se você rodar o projeto no seu emulador neste ponto, verá que ainda não temos uma Toolbar, porque ainda não a incluímos no arquivo xml da nossa Main Activity. Para isso, basta ir até este arquivo, dentro da pasta layout, e inserir a tag include com o atributo layout indicando o arquivo da Toolbar, desta forma:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <include layout="@layout/toolbar"/>
...
</androidx.constraintlayout.widget.ConstraintLayout>
Enter fullscreen mode Exit fullscreen mode

Agora, você deverá ter uma Toolbar simples, apenas com o nome do aplicativo, desse jeito:

toolbar1

5. Criando o Menu

Agora que criamos a Toolbar, precisamos dar algum sentido a ela - implementando um menu! Assim como fizemos com a própria Toolbar, criaremos um arquivo separado para o menu. Para isso, vamos clicar com o botão direito na pasta res e New > Android Resource Directory. Vamos nomeá-lo simplesmente como menu e alterar o seu tipo, também, para menu, desta forma:

newmenu

Agora, com o botão direito na recém-criada pasta menu, selecionamos New > Menu Resource File. Iremos nomear esse arquivo de main_menu. Se tudo der certo, você terá um novo arquivo main_menu.xml dentro da pasta app/res/menu, e poderá editá-lo tanto alterando seu código xml quanto no editor visual do Android Studio, como em qualquer arquivo xml.

(Neste ponto, recomendo que você brinque um pouco no editor visual e explore as diferentes possibilidades de organização de um menu.)

Para este projeto, vamos utilizar um action button de busca e duas opções de funcionalidade dentro de um menu overflow (aqueles três pontinhos que ficam no canto direito da Toolbar, comuns em aplicativos como o WhatsApp). Você pode fazer isso arrastando elementos no editor visual ou editando seu arquivo xml. A princípio, vou apenas nomear as funcionalidades de forma genérica e definir os id's: irei chamar o item de busca de search, a primeira funcionalidade de func1 e, a segunda, de func2. Seu código deverá ficar assim:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:android="http://schemas.android.com/apk/res/android">

    <item
        android:id="@+id/search"
        android:title="Busca"/>
    <item
        android:id="@+id/func1"
        android:title="Funcionalidade 1" />
    <item
        android:id="@+id/func2"
        android:title="Funcionalidade 2" />


</menu>
Enter fullscreen mode Exit fullscreen mode

Perceba que a nossa Busca está aparecendo dentro do menu flutuante - e não ao lado, como gostaríamos. Isso acontece porque ainda não configuramos a propriedade showAsAction do item - que, por default, aparece dentro do menu.

Essa propriedade pode receber 5 valores diferentes:

  1. always
  2. never
  3. ifRoom
  4. withText
  5. collapseActionView

O valor always sempre mostra o item na barra do menu, já o valor never nunca o mostra, e o ifRoom mostra apenas no caso de haver espaço (de acordo com o tamanho da tela e da quantidade de elementos na barra). withText o inclui junto com o atributo title do item, e o collapseActionView permite que a visualização possa ser recolhida. Neste projeto, iremos utilizar apenas os dois primeiros. Para mais detalhes, você pode consultar a documentação oficial.

No item da busca, iremos incluir, portanto, a propriedade app:showAsAction="always", para que ele sempre apareça.

Agora, para que o nosso aplicativo fique mais parecido com um aplicativo moderno e profissional, precisamos incluir o ícone de busca no lugar da palavra Busca, dentro do menu flutuante. Para isso, vamos clicar com o botão direito na pasta drawable - a pasta que guarda todos os arquivos de imagens do nosso projeto - e vamos em New > Vector Asset, que vai abrir a ferramenta Asset Studio, criada para auxiliar desenvolvedores a incluir ícones de uma maneira simples e prática. Para buscar o ícone que queremos, vamos clicar em Clip Art e, na barra de busca, pesquisar pela palavra-chave search, selecionando em seguida o ícone da lupa. Seu nome, por padrão, é ic_baseline_search_24. Vamos mantê-lo assim, mas você pode alterá-lo para um nome mais conciso (como ic_search, por exemplo) se quiser. Como a nossa Toolbar tem uma cor escura, também vamos mudar a cor do ícone para a cor branca, cujo código é #FFFFFF. Se tiver alguma dúvida, consulte a imagem abaixo. Em seguida, é só clicar em Next > Finish. Nosso ícone está criado!

search icon

De volta ao nosso arquivo menu.xml, basta incluir o atributo icon no nosso item de busca e definir o caminho para encontrá-lo dentro da pasta drawable. Seu código final do menu ficará desse jeito:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:android="http://schemas.android.com/apk/res/android">

    <item
        android:id="@+id/search"
        android:title="Busca"
        app:showAsAction="always"
        android:icon="@drawable/ic_baseline_search_24"/>
    <item
        android:id="@+id/func1"
        android:title="Funcionalidade 1" />
    <item
        android:id="@+id/func2"
        android:title="Funcionalidade 2" />

</menu>
Enter fullscreen mode Exit fullscreen mode

6. Inflando o menu na Main Activity

Temos o nosso menu criado, mas ele ainda não está aparecendo em nossa Main Activity, porque precisamos "inflá-lo" chamando a função onCreateOptionsMenu() e o método MenuInflater.inflate(). Esse é o código que você deverá incluir em sua Activity:

 override fun onCreateOptionsMenu(menu: Menu?): Boolean {
        menuInflater.inflate(R.menu.main_menu, menu)
        return true
    }
Enter fullscreen mode Exit fullscreen mode

Note que esse código deverá ser incluído fora do escopo do método onCreate(), como todo override, e que o import android.view.Menu deverá ser incluído no topo do seu código.

Agora, seu aplicativo deverá estar desse jeito:

toolbar2

7. Implementando eventos de clique

Agora que temos alguns botões de ação no menu da nossa Toolbar, vamos implementar eventos de clique a eles! Como esse é um tutorial simples e com foco na implementação da Toobar, cada botão irá apenas disparar um toast (aquelas notificações rápidas que aparecem em uma barra cinza no pé da tela em aplicativos Android).

O método chamado pelo sistema quando o usuário clica em um dos botões do menu é o onOptionsItemSelected(), que passa o MenuItem selecionado como parâmetro. Para identificar o item dentro da nossa pasta de resources, chamamos o getItemId(). Essa função utiliza a sintaxe when e pode gerar alguma confusão por utilizar o operador de seta (->), assim como funções lambda. Por hora, basta entender que não se trata de uma função lambda, e que a condicional when exige a implementação de um else, que, nesse caso, é resolvido com a palavra-chave super. Pode parecer um pouco confuso, mas fica mais claro com a leitura do código. Lembre-se que, no começo, você não precisa necessariamente entender como tudo funciona por baixo dos panos, e que, na programação, é preciso ter paciência. Detalhes podem ser encontrados na documentação oficial do Kotlin.

O código abaixo deverá ser inserido fora do escopo do método onCreate(), e demandará os imports import android.view.MenuItem e import android.widget.Toast. Para mais detalhes sobre notificações toast, também recomendo a leitura da documentação oficial.

override fun onOptionsItemSelected(item: MenuItem) = when (item.itemId) {
        R.id.search -> {
            Toast.makeText(this, "Buscar item", Toast.LENGTH_LONG).show()
            true
        }
        R.id.func1 -> {
            Toast.makeText(this, "Funcionalidade 1", Toast.LENGTH_LONG).show()
            true
        }
        R.id.func2 -> {
            Toast.makeText(this, "Funcionalidade 2", Toast.LENGTH_LONG).show()
            true
        }
        else -> {
            super.onOptionsItemSelected(item)
        }
    }
Enter fullscreen mode Exit fullscreen mode

8. Criando uma nova tela

Nossa Toolbar está ficando cada vez mais pronta. Agora, vamos criar uma nova tela para inserir o botão de retorno, conhecido como up button, que retorna à atividade pai.

Para criar uma nova tela, basta clicar com o botão direito no primeiro arquivo dentro da sua pasta java e New > Activity > Empty Activity. Irei nomeá-la de ChildActivity.

A primeira coisa que vamos fazer nesta nova tela é implementar a Toolbar. Assim como fizemos com a MainActivity, iremos chamar o método setSupportActionBar() com o seguinte código:

val toolbar = findViewById<Toolbar>(R.id.toolbar)
setSupportActionBar(toolbar)
Enter fullscreen mode Exit fullscreen mode

Também iremos torná-la uma filha da tela principal, para que ela herde os eventos de clique que acabamos de implementar. O editor do Android Studio automaticamente irá sinalizar (como faz com os imports pendentes) e pedir para tornar a MainActivity uma classe aberta. O código da ChildActivity ficará assim:

class ChildActivity : MainActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_child)

        val toolbar = findViewById<Toolbar>(R.id.toolbar)
        setSupportActionBar(toolbar)
    }
}
Enter fullscreen mode Exit fullscreen mode

E, no arquivo activity_child.xml, iremos inserir o <include layout="@layout/toolbar"/>. Também vou colocar um TextView simples, com um texto qualquer (no meu caso, será "E aí") e vou aumentar o tamanho dele para 24sp, apenas para facilitar a leitura. Lembrando que estou usando o Constraint Layout no meu projeto, mas você pode usar o que se sentir mais à vontade. Meu código ficará assim:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".ChildActivity">

    <include layout="@layout/toolbar"/>

    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="E aí"
        android:textSize="24sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>
Enter fullscreen mode Exit fullscreen mode

Para navegar até essa tela, vamos voltar ao arquivo activity_main.xml e inserir um botão, cuja posição será abaixo do TextView, também através do Constraint Layout. Vou colocar um texto qualquer no botão ("Opa") e fazer algumas alterações, também, no TextView. Irei mudar seu texto para "Olá Toolbar", aumentar seu tamanho de fonte para 24dp e posicioná-lo um pouco acima do meio no eixo vertical da tela. Meu código ficará assim:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <include layout="@layout/toolbar"/>

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Olá Toolbar"
        android:textSize="24sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.32" />

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:text="Opa"
        app:layout_constraintEnd_toEndOf="@+id/textView"
        app:layout_constraintStart_toStartOf="@+id/textView"
        app:layout_constraintTop_toBottomOf="@+id/textView" />

</androidx.constraintlayout.widget.ConstraintLayout>
Enter fullscreen mode Exit fullscreen mode

No código principal da MainActivity, vamos criar uma variável para armazenar o recurso do botão e implementar um ClickListener para navegar até a ChildActivity. O código ficará assim:

open class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val toolbar = findViewById<Toolbar>(R.id.toolbar)
        setSupportActionBar(toolbar)

        val button = findViewById<Button>(R.id.button)
        button.setOnClickListener {
            val mIntent = Intent(this, ChildActivity::class.java)
            startActivity(mIntent)
        }

    }

    override fun onCreateOptionsMenu(menu: Menu?): Boolean {
        menuInflater.inflate(R.menu.main_menu, menu)
        return true
    }

    override fun onOptionsItemSelected(item: MenuItem) = when (item.itemId) {
        R.id.search -> {
            Toast.makeText(this, "Buscar item", Toast.LENGTH_LONG).show()
            true
        }
        R.id.func1 -> {
            Toast.makeText(this, "Funcionalidade 1", Toast.LENGTH_LONG).show()
            true
        }
        R.id.func2 -> {
            Toast.makeText(this, "Funcionalidade 2", Toast.LENGTH_LONG).show()
            true
        }
        else -> {
            super.onOptionsItemSelected(item)
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

9. Implementando o up button

Para criar o up button, precisamos voltar ao arquivo toolbar.xml, dentro da pasta app/res/layout, e inserir um navigationIcon.

Primeiro, vamos criar o asset dentro da pasta app/res/drawable, como fizemos com o ícone de busca. Mas, desta vez, vamos selecionar o ícone arrow back, identificado pelo nome ic_baseline_arrow_back_24. Também usaremos a cor branca.

Para selecioná-lo dentro do arquivo toolbar.xml, basta inserir o atributo app:navigationIcon="@drawable/ic_baseline_arrow_back_24".

<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="?attr/colorPrimary"
    app:navigationIcon="@drawable/ic_baseline_arrow_back_24">

</androidx.appcompat.widget.Toolbar>
Enter fullscreen mode Exit fullscreen mode

Agora, temos um botão de retorno! Mas ele está aparecendo nas duas telas - tanto na Main quanto na ChildActivity - e não está fazendo nada. Queremos que ele apareça apenas na ChildActivity, e que retorne à atividade principal quando clicado.

Para configurá-lo, basta implementar o método setDisplayHomeAsUpEnabled(Boolean) no código da atividade. Como não queremos que ele apareça na MainActivity, o código implementado nela será supportActionBar?.setDisplayHomeAsUpEnabled(false). Já na ChildActivity, o código será o mesmo, mas com o parâmetro definido como true.

Agora que ele está aparecendo em nossa segunda tela, precisamos configurá-lo para retornar à atividade pai. Para isso, vamos até o arquivo AndroidManifest.xml, dentro da pasta app/manifests, e, dentro da tag referente à nossa ChildActivity, incluímos o código android:parentActivityName="br.com.luizfranco.tutorialtoolbar.MainActivity". Note que esse código será diferente de acordo com o package name do seu aplicativo.

Nossa segunda tela está assim, com o up button funcionando perfeitamente:

toolbar3

10. Últimos ajustes

Nosso aplicativo já está quase idêntico ao que propomos inicialmente, restando apenas alguns ajustes finais. Precisamos alterar o título e a cor do título e do ícone do menu flutuante da Toolbar.

Para mudar o título, basta retornar ao arquivo toolbar.xml e inserir o atributo app:title="". Já para mudar sua cor para branco (já que temos um fundo escuro), é só selecionar app:titleTextColor="@color/white". Vou mudar o nome da minha Toolbar para Toolbar Braba 😎

Já para mudar a cor do ícone do menu flutuante (aqueles três pontinhos no canto direito da Toolbar), vamos, novamente, criar um novo asset dentro da pasta app/res/drawable. O nome desse ícone dentro do Asset Studio é ic_baseline_more_vert_24 e a cor que iremos definir é, novamente, o branco.

Para implementar o novo asset, vamos incluir o código toolbar.overflowIcon = getDrawable(R.drawable.ic_baseline_more_vert_24) em cada uma das activities.

Pronto! Nossa Toolbar está pronta, e você pode personalizá-la e implementá-la da forma que preferir no seu aplicativo 🙌

alt text

11. Considerações finais

Espero que esse tutorial possa ajudar pessoas que estão começando no desenvolvimento de aplicativos Android.

Eu mesmo sou iniciante e tive dificuldades em encontrar um material atualizado, completo e conciso sobre a implementação de uma Toolbar, o que me motivou a escrever este passo-a-passo.

Como ainda estou aprendendo, cabe ressaltar que, se por acaso falei algo errado ou deixei de mencionar alguma boa prática recomendada, por favor, me avise nos comentários!

É isto :)

12. Referências

Top comments (0)