Android UI: Bottom App Bar
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
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.
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.
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.
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.
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.
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.
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.
É 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.
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 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.
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.