
BottomAppBar é um dos novos componentes Android Material que foram introduzidos no Google I / O 2018 . Movendo a gaveta de navegação e o menu do aplicativo para a parte inferior da tela, o BottomAppBar altera radicalmente a aparência dos aplicativos Android.
Na primeira e na segunda parte de nossa série de artigos sobre BottomAppBar, nos encontramos com BottomAppBar e discutimos seus atributos. Também explicamos como implementar a gaveta de navegação e os menus de aplicativos no BottomAppBar.
Comportamento
De acordo com o Material Design, os componentes do aplicativo não são estáticos. Eles podem se mover ou transformar, ou seja, ter algum tipo de comportamento. O design de materiais também forma uma estrutura para esse comportamento. Neste artigo, discutiremos os detalhes de implementação do comportamento recomendado para o BottomAppBar, que é apresentado na página de diretrizes do BottomAppBar .
Layout
A primeira diretriz descreve o layout da BottomAppBar. Aqui está o que é sugerido :
Para telas de aplicativos com significados diferentes, é possível alterar o layout e o conjunto de itens de menu no BottomAppBar. Por exemplo, você pode exibir mais ou menos itens de menu, dependendo do que é mais adequado para uma tela específica.

Com base nesta diretriz, é recomendável usar o layout BottomAppBar nas telas principais , mostrando vários itens de menu e um FAB centralizado (botão de ação flutuante). Nas telas secundárias , cuja transição é realizada a partir das telas principais, o layout BottomAppBar deve consistir em um FAB alinhado à direita e em vários itens de menu adicionais. As transições entre essas duas telas devem ser realizadas corretamente. Gif no topo demonstra essa diretriz.
Agora vamos ver como esse comportamento pode ser implementado. Temos dois arquivos xml na pasta res/menu
para o menu de cada tela:
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/app_bar_search" android:icon="@drawable/baseline_search_white_24" android:title="@string/action_search" app:showAsAction="ifRoom"/> </menu>
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/app_bar_mail" android:icon="@drawable/baseline_mail_white_24" android:title="@string/action_mail" app:showAsAction="ifRoom"/> <item android:id="@+id/app_bar_delete" android:icon="@drawable/baseline_delete_white_24" android:title="@string/action_delete" app:showAsAction="ifRoom"/> <item android:id="@+id/app_bar_archieve" android:icon="@drawable/baseline_archive_white_24" android:title="@string/action_archieve" app:showAsAction="ifRoom"/> </menu>
Quando houver uma transição entre telas, por exemplo, pressionando o botão TOGGLE SCREEN no nosso caso, o layout da BottomAppBar, incluindo o menu e o FAB, deve mudar. Aqui está o código básico para esse comportamento do layout BottomAppBar:
// Hide navigation drawer icon bottom_app_bar.navigationIcon = null // Move FAB from the center of BottomAppBar to the end of it bottom_app_bar.fabAlignmentMode = BottomAppBar.FAB_ALIGNMENT_MODE_END // Replace the action menu bottom_app_bar.replaceMenu(bottomappbar_menu_secondary) // Change FAB icon fab?.setImageDrawable(baseline_reply_white_24)
Se você quiser fazer transições animadas, precisará de código adicional. Você pode estudar o código-fonte anexado no final deste artigo, no qual encontrará animação.
Rolagem
A rolagem é um importante gatilho de comportamento para componentes como BottomAppBar. Na página de diretrizes de Material Design, o seguinte comportamento é recomendado para este caso:
Ao rolar, uma BottomAppBar pode aparecer ou desaparecer:
- Rolar para baixo oculta o BottomAppBar. Se tivesse FAB, desconecta-se do painel e permanece na tela.
- A rolagem para cima mostra o BottomAppBar e o anexa novamente ao FAB, se ele estava lá.
A seguir, é apresentada uma demonstração do comportamento da BottomAppBar ao rolar.

Para usar esse comportamento, BottomAppBar e FAB devem ser filhos diretos de CoordinatorLayout . Em seguida, ativamos o hideOnScroll e configuramos os sinalizadores de rolagem para o BottomAppBar:
<com.google.android.material.bottomappbar.BottomAppBar android:id="@+id/bottom_app_bar" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="bottom" app:fabAlignmentMode="center" app:hideOnScroll="true" app:layout_scrollFlags="scroll|enterAlways"/>
Isso é suficiente para implementar esse comportamento do BottomAppBar.
Elevação
Cada componente no mundo do Design de materiais tem uma elevação semelhante ao nosso mundo físico. No BottomAppBar, a elevação é 8dp e o conteúdo da tela sobe para 0dp . FAB em um estado estático aumenta em 12dp . Os dois componentes que lembraremos neste artigo, Navigation Drawer e Snackbar, aumentam 16dp e 6dp, respectivamente.
Normalmente, o Snackbar é um componente para notificar o usuário que aparece na parte inferior da tela. Mas se houver uma BottomAppBar ou gaveta de navegação na tela, o comportamento do Snackbar deve mudar. Nesses casos, a Snackbar deve ser mostrada acima dos componentes inferiores. Aqui está uma demonstração e um código relacionado a ser implementado:

private fun displayMaterialSnackBar() { val marginSide = 0 val marginBottom = 550 val snackbar = Snackbar.make( coordinatorLayout2, "FAB Clicked", Snackbar.LENGTH_LONG ).setAction("UNDO") { }
Como já mencionamos, o Navigation Drawer aumenta 16dp , o que significa - de acordo com a diretriz -
Os menus que saem do BottomAppBar (por exemplo, Gaveta de Navegação) são abertos como janelas modais um nível acima do BottomAppBar.
A seguir está a implementação da nossa Gaveta de Navegação:

A Gaveta de Navegação é uma janela modal e, portanto, segue a regra de implementação acima.
Os detalhes da implementação desse comportamento são os seguintes. Na pasta res/menu
, deve ser criado um arquivo de menu xml para a Visualização de Navegação , que será usado na Gaveta de Navegação:
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <group android:checkableBehavior="none"> <item android:id="@+id/nav1" android:icon="@drawable/baseline_mail_white_24" android:title="@string/nav_item1" /> <item android:id="@+id/nav2" android:icon="@drawable/baseline_bookmark_white_24" android:title="@string/nav_item2" /> <item android:id="@+id/nav3" android:icon="@drawable/baseline_message_white_24" android:title="@string/nav_item3" /> <item android:id="@+id/nav4" android:icon="@drawable/baseline_note_white_24" android:title="@string/nav_item4" /> <item android:id="@+id/nav5" android:icon="@drawable/baseline_location_on_white_24" android:title="@string/nav_item5" /> <item android:id="@+id/nav6" android:icon="@drawable/baseline_sync_white_24" android:title="@string/nav_item6" /> <item android:id="@+id/nav7" android:icon="@drawable/baseline_cloud_upload_white_24" android:title="@string/nav_item7" /> <item android:id="@+id/nav8" android:icon="@drawable/baseline_favorite_white_24" android:title="@string/nav_item8" /> <item android:id="@+id/nav9" android:icon="@drawable/baseline_chrome_reader_mode_white_24" android:title="@string/nav_item9" /> <item android:id="@+id/nav10" android:icon="@drawable/baseline_select_all_white_24" android:title="@string/nav_item10" /> <item android:id="@+id/nav11" android:icon="@drawable/baseline_sort_white_24" android:title="@string/nav_item11" /> <item android:id="@+id/nav12" android:icon="@drawable/baseline_access_time_white_24" android:title="@string/nav_item12" /> <item android:id="@+id/nav13" android:icon="@drawable/baseline_data_usage_white_24" android:title="@string/nav_item13" /> </group> </menu>
Em seguida, um arquivo de layout deve ser criado para o fragmento usando a Gaveta de Navegação:
<?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:id="@+id/navigation_view_layout" android:layout_width="match_parent" android:layout_height="wrap_content" app:behavior_hideable="true" app:layout_behavior="@string/bottom_sheet_behavior"> <com.google.android.material.navigation.NavigationView android:id="@+id/navigation_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="bottom" android:layout_marginTop="4dp" android:paddingBottom="40dp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.0" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/view2" app:menu="@menu/bottom_nav_drawer_menu" app:theme="@style/NavigationDrawerStyle" /> <TextView android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="12dp" android:layout_marginTop="16dp" android:fontFamily="@font/rubik_medium" android:text="@string/bottom_sheet_name" android:textColor="@color/colorAccent" android:textSize="18sp" android:textStyle="bold" app:layout_constraintStart_toEndOf="@+id/imageView" app:layout_constraintTop_toTopOf="parent" /> <TextView android:id="@+id/textView2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="2dp" android:text="@string/bottom_sheet_email" android:textColor="@color/colorAccent" app:layout_constraintStart_toStartOf="@+id/textView" app:layout_constraintTop_toBottomOf="@+id/textView" /> <ImageView android:id="@+id/imageView" android:layout_width="48dp" android:layout_height="48dp" android:layout_marginStart="24dp" android:background="@drawable/baseline_account_circle_black_48" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="@+id/textView" /> <View android:id="@+id/view2" android:layout_width="match_parent" android:layout_height="2dip" android:layout_marginTop="15dp" android:background="#447e7e7e" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.0" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/textView2" /> <ImageView android:id="@+id/close_imageview" android:layout_width="24dp" android:layout_height="24dp" android:layout_marginTop="8dp" android:layout_marginEnd="16dp" android:layout_marginBottom="8dp" android:background="@drawable/baseline_close_black_24" android:visibility="gone" app:layout_constraintBottom_toBottomOf="@+id/textView2" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="@+id/textView" /> </androidx.constraintlayout.widget.ConstraintLayout>
Este arquivo de layout contém a Visualização de Navegação e outros componentes que compõem o layout da Gaveta de Navegação. Para criar esse layout, precisamos de uma classe de fragmento que estenda BottomSheetDialogFragment:
class BottomNavigationDrawerFragment: BottomSheetDialogFragment() { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { return inflater.inflate(R.layout.fragment_bottom_navigation_drawer, container, false) } override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) navigation_view.setNavigationItemSelectedListener { menuItem ->
Quando você clica no ícone da Gaveta de Navegação, é criada uma instância desse fragmento, que é mostrada como uma janela modal:
override fun onOptionsItemSelected(item: MenuItem?): Boolean { when (item!!.itemId) { android.R.id.home -> { val bottomNavDrawerFragment = BottomNavigationDrawerFragment() bottomNavDrawerFragment.show(supportFragmentManager, bottomNavDrawerFragment.tag) } } return true }
Este artigo conclui nossa série de artigos sobre o BottomAppBar. Você pode encontrar o código fonte deste artigo no Github . Comente e faça perguntas.
← Implementação do BottomAppBar. Parte 1: Componentes materiais para Android
← Implementação do BottomAppBar. Parte 2: Controle de menu e gaveta de navegação