Android UI: Bottom App Bar

Lucas
Android Dev BR
Published in
10 min readJun 12, 2019

Uma barra de ações ergonômica, flexível e… bonita.

No meu último artigo sobre UI do Android eu falei um pouco sobre o Bottom Sheet. E dando continuidade ao assunto sobre os componentes de UI, o alvo desta vez é o Bottom App Bar.

O Material Design 2 trouxe para o público uma série de novidades que refletem no comportamento, usabilidade e aparência dos aplicativos.

Eu nunca gostei da primeira versão da linguagem, porque os conceitos eram muito básicos, o sistema de cores não era tão legal e a única coisa que escapava era alguns componentes, como o Floating Action Button.

A segunda versão da linguagem veio com uma repaginada total, focando em aplicativos monótonos, uso do modo escuro e assim vai. Os componentes também foram uma boa adição, principalmente com a chegada do Bottom App bar, que mudou bastante o contexto de navegação do Android.

Utilizando o Bottom App Bar

Este componente fora introduzido na versão 28 da biblioteca de suporte do Android, e também está disponível na versão 1 do artefato do próprio Material Design.

// AndroidX
implementation "com.google.android.material:material.1.0.0"
// AppCompat
implementation "com.android.support:design:28.0.0"

Casos de uso

  • Interfaces de dispositivos móveis, não sendo recomendado o uso em aplicações web
  • Acessar um menu inferior, como o Navigation Drawer

Recomendações

  • Ter entre 2 e 5 itens no menu
  • Não ser utilizado em interfaces Web e nem quando já existir um componente de navegação inferior, como o Bottom Navigation View

Implementação

A implementação é simples ao tratar-se do componente em si. Como ele é um encapsulador de ações para o seu aplicativo, a sua customização fica um tanto quanto dividida e você tem liberdade para definir qual será o comportamento do componente em determinadas ações, principalmente quando houver necessidade de acessar um menu de navegação.

O exemplo acima é bem simples e mostra como o componente pode ser utilizado em sua versão mais simples, sem nenhuma customização. Obviamente, essa não será a versão final que irá com seu produto. Há ainda muita coisa para ser feita, entretanto ela servirá para explicar alguns casos.

O componente aqui apresentado utiliza os comportamentos existentes no CoordinatorLayout para também criar sua própria identidade visual, como é o caso do Cradle, que é aquele espaço ou buraco em que o Floating Action Button fica. Esse comportamento é realizado quando você usa o atributo layout_anchor que pertence ao CoordinatorLayout. Tem também outros atributos como o hideOnScroll mas falaram mais disso posteriormente.

Temas

Uma parte muito importante e que eu não poderia deixar de citar é do estilo do componente e como isso o afeta.

Fiz um teste simples usando um tema padrão e talvez o mais utilizado até o momento: Theme.AppCompat

Demonstração do tema do componente com AppCompat

O resultado foi esse. O código continua sendo o mesmo e a única modificação é a presença do atributo para adicionar esse ícone de navegação. Quando não utilizamos o tema recomendado (Theme.MaterialComponents), esse componente perde a habilidade de customização automática que ele possui. A recomendação é que você sempre utilize esses novos estilos do Material ao utilizar esse componente.

Tá.. legal! Mas meu projeto já utiliza esses temas do AppCompat e não posso alterá-los de forma alguma, como faço?

Basta utilizar o seguinte atributo diretamente no componente que o problema será resolvido:

style=”@style/Widget.MaterialComponents.BottomAppBar”

Customização

Existem diversos atributos para o componente que ditam como ele vai se comportar, de modo geral. É uma customização opcional, mas que por padrão já tem seus valores definidos.

Alterando a cor de fundo

app:backgroundTint

O Bottom App Bar gerencia ele mesmo o seu próprio background. Segundo a documentação, isso permite esse efeito de “buraco” para o FAB quando o mesmo é anexado ao componente. Ou seja, não faça quaisquer alterações ao atributo background, pois isso vai afetar o comportamento do componente.

Não utilize o atributo android:background ou o método setBackground() pois irá afetar o comportamento do componente.

Se você deseja alterar a cor dele, você pode fazer isso usando o atributo app:backgroundTint via XML.

Demonstração da troca de cores do Bottom App Bar

Modo de alinhamento do FAB anexado

app:fabAlignmentMode

Outra coisa que pode ser alterada é o modo como o FAB será alinhado quando ele estiver anexado ao componente. Atualmente existem duas opções: center e end.

A primeira opção refere-se ao centro do componente, e as imagens e o GIF acima já mostram isso. É o comportamento padrão de alinhamento.

Demonstração do alinhamento centralizado do FAB

A segunda define que o FAB será alinhado no fim do componente, ou seja, no lado direito ou esquerdo — caso o modo RTL esteja ativado.

Exibição do alinhamento do FAB com e sem modo RTL

Cradle, caverna, berço, que seja…

app:fabCradleMargin

app:fabCradleRoundedCornerRadius

app:fabCradleVerticalOffset

Uma das coisas mais legais desse componente foi o “notch” reverso que ele ganhou — e olha que os notchs estão na moda nos celulares atuais.

Além de ser um diferencial para o componente, tem um efeito estético muito positivo. Você pode chamar o Cradle como quiser: berço, notch, caverna, buraco, tanto faz… o importante é utilizar quando possível, para dar uma sutileza pro usuário. Vale salientar que não é recomendado que o FAB fique flutuando acima do Bottom App Bar, pois isso dificultaria pro usuário, já que ele teria que deslocar mais o dedo para efetuar o toque.

Demonstração do fabCradleMargin

O app:fabCradleMargin altera a distância entre o Bottom App Bar e o FAB, ou seja, os aproximando ou distanciando.

Já o app:fabCradleRoundedCornerRadius vai afetar as curvas (direita e esquerda) do Cradle. Ela pode ser uma curva (ou borda, se preferir) extremamente reta ou extremamente aberta.

Deixar o atributo com o valor 0dp fará com que ele seja totalmente reto, assim como 100dp o deixará bem aberto.

Demonstração do fabCradleRoundedCornerRadius

E por último, mas não menos importante, temos o app:fabCradleVerticalOffset que altera a distância vertical entre o FAB e o Bottom App Bar. Não é recomendado que o FAB fique muito distante dele.

O valor 0dp faz com que o centro do FAB fique alinhado com o topo do Bottom App Bar, que é o efeito padrão.

Demonstração do fabCradleVerticalOffset

Efeitos na rolagem de tela

app:hideOnScroll

Outra coisa bastante legal deste componente é que você pode fazer com que ele se esconda quando o usuário rolar a tela, isso sem muito esforço (muito pouco mesmo, muito mesmo).

A única coisa que você precisa estar atento é que para que o efeito possa ocorrer como o esperado, o seu container precisa estar dentro de um NestedScrollView, e a mágica vai acontecer (na verdade, o CoordinatorLayout vai acontecer).

Você também pode usar uma RecyclerView independente (sem um container) que o mesmo comportamento vai ocorrer, mas a regra principal é que, para este componente, você utilize o CoordinatorLayout. Isso deve se ao fato de o componente usar de vários atributos dele para criar sua identidade visual, o uso deste componente com o ConstraintLayout, por exemplo, não é recomendado e talvez não funcione como o esperado.

Isso deve se ao fato de o componente usar de vários atributos dele para criar sua identidade visual, o uso deste componente com o ConstraintLayout, por exemplo, não é recomendado e talvez não funcione como o esperado.

Basicamente, se você quer que o seu Bottom App Bar suma quando o usuário rolar a tela, define o atributo como true, caso contrário, como false. O padrão é false.

Demonstração do hideOnScroll

É importante lembrar que o uso desse atributo vai muito mais da usabilidade e necessidade do seu aplicativo. É muito importante não cortar nenhuma informação da tela pro usuário.

Menu de ações

Assim como a Toolbar, o componente no qual estamos falando também pode ter um menu de ações e até mesmo de opções (aquele menu de três pontos que exibe algumas opções pro usuário). A configuração é bem semelhante, já que ele também é uma Toolbar, então tudo que você precisa fazer é:

  • Criar um recurso de menu com os itens que você deseja.
  • Fazer o setup do ActionBar usando o Bottom App Bar e sobrescrever o método onCreateOptionsMenu para definir o menu de opções da Action Bar.

Feito isso, você terá um menu de opções para o seu componente.

Demonstração do menu de opções

Tratando o clique nos itens do menu

Como foi falado anteriormente, essa parte do menu de opções não mudou muita coisa se formos comparar com a Toolbar. O mesmo serve para o tratamento de cliques do menu de opções. Você o faz sobrescrevendo um método em sua Activity.

Você também pode usar o método setOnMenuItemClickListener do componente, caso preferir.

Como podemos ver, não mudou muita coisa se compararmos com a Toolbar. Quase nada.

Tratando clique no menu de opções

Tratando o clique no ícone de navegação

Como podemos ver ao longo desse artigo, é possível definir um ícone próprio para o ícone de navegação desse componente. Além disso, também é possível fazer um tratamento de cliques nesse carinha e de uma maneira muito simples.

Saber disso será muito útil para o que vem a seguir. Mas saiba que, com isso, você pode fazer muita coisa— contanto que siga as regras do Material Design.

Demonstração do clique no ícone de navegação

Criando um menu de navegação

Esse é o momento em que a gente para de só tratar ações e começa a implementar comportamentos que, nesse caso, irá definir o que o aplicativo fará quando o usuário clicar no ícone de navegação. Nesse exemplo atual, iremos exibir um menu usando NavigationView e BottomSheet.

É bem importante usar esses dois componentes porque você tem acesso à muitas opções de customização, como um header, diferença de item normal para item selecionado e assim por diante.

Antes de tudo, precisamos criar alguns recursos, como o menu, que vai exibir os itens quando o usuário clicar no ícone de navegação. É um recurso de menu normal mesmo, como se você estive criando para um NavigationDrawer.

O próximo passo será criar o layout do nosso BottomSheet. Nesse caso, não irei utilizar um BottomSheet como componente da View, ele será um Dialog.

O layout é bem simples também e só deve conter o NavigationView, que é o carinha que vai exibir o menu, como podemos ver o atributo app:menu que faz referência ao amiguinho que acabamos de criar.

E então tudo que você precisa fazer é criar o Fragment para o layout acima.

Depois disso basta instancia-lo e exibir ele quando o usuário clicar no ícone de navegação do Bottom App Bar. Para isso, você pode usar o método que fora exibido anteriormente ou sobrescrever o método onOptionsItemSelected, buscando pelo id android.R.id.home, pois é o padrão para esse ícone (desde a ActionBar).

O resultado, como veremos abaixo é o que você já deve ter imaginado: um BottomSheet exibindo o menu de navegação!

Ah, eu quase ia me esquecendo… para tratar o clique nesses itens do menu de navegação você o faz diretamente no BottomSheet. Melhor ainda, todas as customizações possíveis de se fazer no NavigationView você pode fazer pelo BottomSheet!

Feito isso, você terá tratado o clique em cada item do menu de navegação.

Chegamos ao fim. Finalmente.

Eu sei, o artigo ficou um pouco grandinho, mas acredito que vá servir como uma base para que você possa utilizar o componente. Existe muita coisa para falar desse cara, mas deu para cobrir o básico e eu acredito que isso irá despertar a curiosidade em você para buscar as outras opções de customizações e possibilidades que esse componente tem.

Uma dica que eu dou é ler a documentação do Material Design a respeito de como esse componente deve ser utilizado. Tem muita dica bacana por lá e você pode evitar mal uso do componente — que afeta negativamente a experiência do usuário.

Continue lendo

--

--