DEV Community

Luiz Franco
Luiz Franco

Posted on

12 2

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

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay