Implementando uma Toolbar no Android Studio com Kotlin
Luiz Franco
Posted on December 23, 2020
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:
Na segunda tela, há ainda uma seta para retornar à tela principal, conhecida como up button:
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).
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.
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>
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.
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>
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)
- 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))
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>
Agora, você deverá ter uma Toolbar simples, apenas com o nome do aplicativo, desse jeito:
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:
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>
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:
always
never
ifRoom
withText
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!
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>
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
}
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:
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)
}
}
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)
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)
}
}
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>
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>
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)
}
}
}
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>
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:
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 🙌
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
Posted on December 23, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.