Le Bottom App bar sur android


A la conférence Google I/O 2018, google a introduit aux composants material un nouveau composant appelé Bottom App Bar .Il se place en bas de la fenêtre contrairement à la Toolbar qui se place en haut de la fenêtre.

Vous pouvez voir ce composant comme une toolbar avec comme possibilité de se raccrocher à un FloatingactionButton et une grande flexibilité de pouvoir positionner le bouton flottant à différents endroits.

La librairie des composants material fournit de nouveaux styles pour le bottom app bar, lui permettant d’avoir l’apparence des composants de la mise à jour du material design.

Table des matières

Créer un nouveau projet

Créer un nouveau projet en allant sur File->New->New Project. Sélectionnez Empty activity puis cliquez sur Next. Dans la fenêtre qui s’affiche ,nommez votre projet par BottomAppBar , puis dans le champ language, sélectionnez votre langage de programmation et enfin cliquez sur Finish.

creation du projet bottomappbar

Ajouter la librairie de composants material

Pour utiliser le composant BottomAppBar, vous devez ajouter la librairies des composants material comme dépendance dans votre projet.Pour cela Ouvrez le fichier build.gradle(Module:app) puis ajoutez la dépendance suivante comme suit

dependencies {
    ...
    implementation 'com.google.android.material:material:1.1.0-alpha10'
    ...
}

Utilisation Basique

Créez d’abord une vecteur drawable pour l’icon de navigation du bottomAppBar en allant sur File->New ->Vector Asset puis choisissez une icon. N’oubliez pas de définir la couleur de l’icon à #ffffff.

Pour ajouter un simple BottomAppBar dans votre projet, ouvrez le fichier res/layout/activity_main.xml puis ajoutez le contenu suivant

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

    <com.google.android.material.bottomappbar.BottomAppBar
            android:id="@+id/bar"
            android:layout_width="match_parent"
            android:layout_gravity="bottom"
            android:layout_height="wrap_content"

            android:backgroundTint="@color/colorPrimary"
            app:navigationIcon="@drawable/bottomappbarnavigation"/>

</androidx.coordinatorlayout.widget.CoordinatorLayout>

Résultat

simple bottomappbar

Accrocher un bouton flottant au BottomAppBar

Créer une vector drawable comme précédemment pour représenter l’icon du bouton flottant.

Vous pouvez raccrocher un bouton flottant au BottomAppBar avec l’attribut app:layout_anchor ou dans le code avec la méthode fab.setLayoutParams() en Java et la méthode fab.setLayoutParams en Kotlin

Raccrocher le bouton flottant au bottom app bar dans le code

  val layoutParams:CoordinatorLayout.LayoutParams=fab.layoutParams as CoordinatorLayout.LayoutParams
        layoutParams.anchorId=R.id.bar
        fab.layoutParams=layoutParams
   CoordinatorLayout.LayoutParams layoutParams = (CoordinatorLayout.LayoutParams) fab.getLayoutParams();
        layoutParams.setAnchorId(R.id.bar);
        fab.setLayoutParams(layoutParams);

Raccrocher le bouton flottant au bottom app bar dans le fichier layout

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

    <com.google.android.material.bottomappbar.BottomAppBar
            android:id="@+id/bar"
            android:layout_width="match_parent"
            android:layout_gravity="bottom"
            android:layout_height="wrap_content"

            android:backgroundTint="@color/colorPrimary"
            app:navigationIcon="@drawable/bottomappbarnavigation" />
    <com.google.android.material.floatingactionbutton.FloatingActionButton
            android:id="@+id/fab"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
          app:layout_anchor="@id/bar"
          android:src="@drawable/add"
          app:tint="@android:color/white"/>

</androidx.coordinatorlayout.widget.CoordinatorLayout>

Résultat:

bottom app bar avec bouton flottant

Si vous n’avez pas encore lu le tutoriel sur les boutons flottant, cliquez ici

Le nouveau style material

Pour appliquer au composant BottomAppBar le nouveau style des composants material, le thème de votre application doit hériter d’un des thèmes de la librairie des composants material( Theme.MaterialComponents ).Voir l’exemple suivant

<style name="AppTheme" parent="Theme.MaterialComponents.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
 </style>

Si le thème de votre application n’hérite pas d’un des thèmes de la librairie des composants material( les différentes variantes du du thème Theme.MaterialComponents ), vous devez directement appliquer au bottom app bar un des styles du bottom app bar de la librairie des composants material comme suit

 <com.google.android.material.floatingactionbutton.FloatingActionButton
            android:id="@+id/fab"
            style="@style/Widget.MaterialComponents.BottomAppBar"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_anchor="@id/bar" 
            android:src="@drawable/add"
            app:tint="@android:color/white"
    />

Les thèmes

Vous pouvez créer un thème de couleur, de forme et de typographie sur le bottom App Bar. Pour cela vous devez directement appliquer un style au bottom app bar avec le style de base Widget.MaterialComponents.BottomAppBar . Il existe deux autres variantes de style qui hérite du style de base Widget.MaterialComponents.BottomAppBar . Il s’agit des styles Widget.MaterialComponents.BottomAppBar.Colored et Widget.MaterialComponents.BottomAppBar.PrimarySurface. Les styles Widget.MaterialComponents.BottomAppBar et Widget.MaterialComponents.BottomAppBar.PrimarySurface sont les mêmes.

La différence entre les deux style qui se termine par .Colored et .PrimarySurface est la l’attribut de couleur utilisé pour définir la couleur d’arrière plan du bottomAppBar.

Couleur

Pour changer la couleur d’arrière plan du bottomAppBar , vous devez utiliser l’attribut backgroundTint. La variante qui se termine par .Colored utilise la couleur défini dans l’attribut de couleur colorPrimary pour définir la couleur d’arrière plan tandis que la variante qui se termine par .PrimarySurface utilise la couleur définir dans l’attribut de couleur colorSurface.

La couleur des items de menu et de navigation peuvent être changé avec l’attribut materialThemeOverlay. Les valeurs des attributs d’un materialThemeOverlay viennent se superposer et changer les valeurs de style définit sur un composant.

Il existe deux variants de style materialThemeOverlay tels que ThemeOverlay.MaterialComponents.BottomAppBar.Primary et ThemeOverlay.MaterialComponents.BottomAppBar.Surface qui hérite du style ThemeOverlay.MaterialComponents.BottomAppBar. Ces deux variantes ont deux attributs colorControlNormal(pour personnaliser la couleur des icons des items de menu et l’item de navigation)  et actionMenuTextColor(Pour personnalisé la couleur du texte du menu flottant)  .

Dans le style ThemeOverlay.MaterialComponents.BottomAppBar.Primary les attributs colorControlNormal et actionMenuTextColor utilisent la couleur défini dans l’attribut colorOnPrimary et dans le style ThemeOverlay.MaterialComponents.BottomAppBar.Surface , les attributs colorControlNormal et actionMenuTextColor utilisent la couleur défini dans l’attribut material_on_surface_emphasis_medium.

Les attributs du Bottom App bar

Voici la liste des attributs du bottom app bar que vous pouvez utiliser

Bottom App Bar Attributes

FeatureRelevant attributes
Background Tintapp:backgroundTint
FAB Alignment Modeapp:fabAlignmentMode
FAB Animation Modeapp:fabAnimationMode
FAB Cradle Marginapp:fabCradleMargin
FAB Cradle Corner Radiusapp:fabCradleRoundedCornerRadius
FAB Vertical Offsetapp:fabCradleVerticalOffset
Hide on scrollapp:hideOnScroll
Add Padding for Bottom Insetsapp:paddingBottomSystemWindowInsets
Add Padding for Left Insetsapp:paddingLeftSystemWindowInsets
Add Padding for Right Insetsapp:paddingRightSystemWindowInsets

Ajouter un menu au Bottom App Bar

Vous pouvez ajouter un menu au Bottom App Bar directement dans le fichier xml de la vue ou dans le code

Méthode1: On ajouter un menu au Bottom App Bar dans le fichier xml grâce à l’attribut app:menu

L’exemple suivant ajoute un menu au Bottom App Bar grâce à l’attribut app:menu

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

    <com.google.android.material.bottomappbar.BottomAppBar
            android:id="@+id/bar"
            android:layout_width="match_parent"
            android:layout_gravity="bottom"
            android:layout_height="wrap_content"
            android:backgroundTint="@color/colorPrimary"
            app:menu="@menu/menu"
            app:navigationIcon="@drawable/bottomappbarnavigation" />
    <com.google.android.material.floatingactionbutton.FloatingActionButton
            android:id="@+id/fab"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_anchor="@id/bar"
            android:src="@drawable/add"
            app:tint="@android:color/white"
    />

</androidx.coordinatorlayout.widget.CoordinatorLayout>

Méthode2: Vous pouvez aussi ajouter un menu au Bottom App Bar dans le code grâce à la méthode replaceMenu de la manière suivant

package com.example.bottomappbar

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.Menu
import com.google.android.material.bottomappbar.BottomAppBar

class MainActivity : AppCompatActivity() {

    private lateinit var mBottomAppBar: BottomAppBar
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        mBottomAppBar=findViewById(R.id.bar)
        mBottomAppBar.replaceMenu(R.menu.menu)
    }

}
package com.example.bottomappbarjava;

import androidx.appcompat.app.AppCompatActivity;
import androidx.coordinatorlayout.widget.CoordinatorLayout;

import android.os.Bundle;

import com.google.android.material.bottomappbar.BottomAppBar;
import com.google.android.material.floatingactionbutton.FloatingActionButton;

public class MainActivity extends AppCompatActivity {

   private BottomAppBar mBottomAppBar;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mBottomAppBar=findViewById(R.id.bar);
        mBottomAppBar.replaceMenu(R.menu.menu);

    }
}

Méthode3: Créer le menu du bottom app bar à partir du menu de l’activité ou du fragment

Une autre manière d’ajouter un menu au bottom app bar est d’appeler la méthode setSupportActionBar () de l’activité depuis une activité ou un fragment.Tout comme une Toolbar, cela configure les méthodes callback Activity#onCreateOptionsMenu() et Activity#onOptionsItemSelected() pou créer et gérer les actions de l’activité auquel se branche une Toolbar. Donc dès que cette méthode est appelée, le bottom app bar est automatiquement branché à ces méthodes callback.

Pour appeler la méthode setSupportActionBar(), votre activité doit hérité de la classe AppCompatActivity d’AndroidX et en plus vous devez utiliser un thème sans actionBar comme par exemple le Theme.MaterialComponents.Light.NoActionBar( .NoActionBar ).

Note:Lorsque vous ajouter le menu avec setSupportActionBar() ,cela vous permet aussi de savoir quand l’item android.R.id.home est cliqué (L’utilisateur souhaitez faire un retour en arrière) .

Appeler la méthode setSupportActionBar depuis une actvité

Vous pouvez appeler cette méthode depuis une activité de la manière suivante

 mBottomAppBar=findViewById(R.id.bar)
 setSupportActionBar(mBottomAppBar)
   mBottomAppBar=findViewById(R.id.bar);
   setSupportActionBar(mBottomAppBar);

Appeler la méthode setSupportActionBar() depuis un fragment

Si le menu que vous souhaitez ajouter au bottom app bar est dans un fragment vous devez effectuer quelque action pour que cela puis s’afficher dans le bottom app bar déclarer dans la vue de l’activité.

Vous devez appeler la méthode setHasOptionsMenu() dans la méthode Oncreate() du fragment pour demander à l’activer d’ajouter les menu créer dans le fragment au menu de l’activité

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setHasOptionsMenu(true)
}
 @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setHasOptionsMenu(true);
    }

Puis vous devez appeler la méthode setSupportActionBar() dans la méthode onCreateView du fragment comment suit

  override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        val activity=(requireActivity() as AppCompatActivity)
        val view=inflater.inflate(R.layout.activity_main,container,false)
        val  mBottomAppBar:BottomAppBar=view.findViewById(R.id.bar)
        activity.setSupportActionBar(mBottomAppBar)
        return view
    }
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

        AppCompatActivity activity=(AppCompatActivity)requireActivity();
        View view=inflater.inflate(R.layout.activity_main,container,false);
        BottomAppBar mBottomAppBar=view.findViewById(R.id.bar);
        activity.setSupportActionBar(mBottomAppBar);
        return view;

    }

Créer le menu

Vous devez ensuite créer le menu dans l’activité comme suit.

 override fun onCreateOptionsMenu(menu: Menu?): Boolean {
        menuInflater.inflate(R.menu.menu,menu)
        return true
    }
   @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu,menu);
        return true;
    }

Vous devez ensuite créer le menu dans le fragment comme suit.

 override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
        inflater.inflate(R.menu.menu,menu)
    }

   @Override
    public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
        inflater.inflate(R.menu.menu,menu);
    }

Gérer les clics sur les items de menu quand la méthode setSupportActionBar() est appelée

Vous pouvez gérer les clics sur les items de menu dans la méthode onOptionsItemSelected comme vous le faites avec une Toolbar

 override fun onOptionsItemSelected(item: MenuItem): Boolean {

        when(item.itemId){
         R.id.menu_appel->{
           true
         }
         R.id.menu_message ->{
             true
         }
         else -> {
             false
         }

        }
        return super.onOptionsItemSelected(item)
    }
   @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {

        switch (item.getItemId()){
            case  R.id.menu_appel:
            return true;
            case  R.id.menu_message:
              return true;
          
        }
        return super.onOptionsItemSelected(item);
    }

Gérer le clics des items pour la création de menu dans le fichier xml ou grâce à la méthode replaceMenu

Si vous avez créer le menu du bottom app bar directement depuis le fichier xml de la vue ou si vous l’avez créé grâce à la méthode replaceMenu(),vous devez gérer le clic des items de la manière suivante

  mBottomAppBar.setOnMenuItemClickListener {item ->
            when(item.itemId){
                R.id.menu_appel->{
                    true
                }
                R.id.menu_message ->{
                    true
                }
                else -> {
                    false
                }

            }
        }
   mBottomAppBar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
           @Override
           public boolean onMenuItemClick(MenuItem item) {
               switch (item.getItemId()){
                   case  R.id.menu_appel:
                       return true;
                   case  R.id.menu_message:
                       return true;
                       
               }
               return false;
           }
       });

Voici le menu utilisé dans les exemples précédents

<?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">
    <item
     android:id="@+id/menu_appel"
     android:title="Appeler"
     android:icon="@drawable/appel"
    />
   <item
   android:id="@+id/menu_favori"
   android:title="Favori"
   android:icon="@drawable/favorie"
   />
   <item
    android:id="@+id/menu_message"
    android:title="Message"
   />
</menu>

Si vous souhaitez forcer l’affichage des icons du menu, utilisez l’attribut app:showAsAction= »ifRoom » dans chaque item de menu.

Voici le résultat obtenu lorsque vous ajoutez un menu

Ajouter l’item de navigation.

Vous pouvez ajouter l’item de navigation avec l’attribut app:navigationIcon comme dans l’exemple suit

  <com.google.android.material.bottomappbar.BottomAppBar
            android:id="@+id/bar"
            app:navigationIcon="@drawable/bottomappbarnavigation" />

Ou vous pouvez aussi ajouter l’item de navigation dans le code de la manière suivante

 mBottomAppBar.setNavigationIcon(R.drawable.bottomappbarnavigation)
 mBottomAppBar.setNavigationIcon(R.drawable.bottomappbarnavigation);

Note:La gestion du clic de l’item de Navigation se fait comme vous le faites pour les autres item du Bottom App bar .C’est à dire géré le clic soir dans la méthode setOnMenuItemClickListener() ,soit dans la méthode onOptionsItemSelected().

Positionner le bouton flottant au centre

Il s’agit du positionnement par défaut lorsque vous raccrocher le bouton flottant au Bottom App bar.Vous pouvez manuellement positionner le bouton flottant au centre grâce à la méthode fabAlignmentMode en définissant la valeur à center.

<com.google.android.material.bottomappbar.BottomAppBar
            android:id="@+id/bar"
            android:layout_width="match_parent"
            android:layout_gravity="bottom"
            android:layout_height="wrap_content"
            android:backgroundTint="@color/colorPrimary"
           app:fabAlignmentMode="center"
            app:navigationIcon="@drawable/bottomappbarnavigation" />

Positionner le bouton flotant à droit

Vous pouvez manuellement positionner le bouton flottant à droit grâce à la méthode fabAlignmentMode en définissant la valeur à end.

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

    <com.google.android.material.bottomappbar.BottomAppBar
            android:id="@+id/bar"
            android:layout_width="match_parent"
            android:layout_gravity="bottom"
            android:layout_height="wrap_content"
            android:backgroundTint="@color/colorPrimary"
           app:fabAlignmentMode="end"
            app:navigationIcon="@drawable/bottomappbarnavigation" />
    <com.google.android.material.floatingactionbutton.FloatingActionButton
            android:id="@+id/fab"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_anchor="@id/bar"
            android:src="@drawable/add"
            app:tint="@android:color/white"
    />

</androidx.coordinatorlayout.widget.CoordinatorLayout>

L’image suivante illustre ce que vous devez obtenir

bottom app bar avec bouton flottant à droit

Le diamètre du creux du bottom app bar

L’attribut fabCradleVerticalOffset  vous permet de définir la distance du décalage vertical entre le bouton flottant et le bottom app par rapport au creux.Si sa valeur est définir à 0dp,le centre du bouton flottant sera aligner avec le haut du bottom app bar.

Bouton flottant resorti

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

    <com.google.android.material.bottomappbar.BottomAppBar
            android:id="@+id/bar"
            android:layout_width="match_parent"
            android:layout_gravity="bottom"
            android:layout_height="wrap_content"
            android:backgroundTint="@color/colorPrimary"
           app:fabAlignmentMode="end"
            app:fabCradleVerticalOffset="20dp"
            app:navigationIcon="@drawable/bottomappbarnavigation" />
    <com.google.android.material.floatingactionbutton.FloatingActionButton
            android:id="@+id/fab"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_anchor="@id/bar"
            android:src="@drawable/add"
            app:tint="@android:color/white"
    />

</androidx.coordinatorlayout.widget.CoordinatorLayout>

Bouton flottant enfoncé

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

    <com.google.android.material.bottomappbar.BottomAppBar
            android:id="@+id/bar"
            android:layout_width="match_parent"
            android:layout_gravity="bottom"
            android:layout_height="wrap_content"
            android:backgroundTint="@color/colorPrimary"
           app:fabAlignmentMode="end"
            app:fabCradleVerticalOffset="0dp"
            app:navigationIcon="@drawable/bottomappbarnavigation" />
    <com.google.android.material.floatingactionbutton.FloatingActionButton
            android:id="@+id/fab"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_anchor="@id/bar"
            android:src="@drawable/add"
            app:tint="@android:color/white"
    />

</androidx.coordinatorlayout.widget.CoordinatorLayout>
profondeur du creux bottom app bar

Le rayon des coins du creux du bottom app bar

L’attribut app:fabCradleRoundedCornerRadius vous permet de définir le rayon des coins du creux du bottom app bar. Lorsque la valeur du rayon est à 0, les coins du creux sont carré et lorsque la valeur est supérieur à zéro,les coins sont arrondi.

L’exemple suivant défini la valeur du rayon à 20

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

    <com.google.android.material.bottomappbar.BottomAppBar
            android:id="@+id/bar"
            android:layout_width="match_parent"
            android:layout_gravity="bottom"
            android:layout_height="wrap_content"
            android:backgroundTint="@color/colorPrimary"
           app:fabAlignmentMode="end"
            app:fabCradleVerticalOffset="0dp"
            app:fabCradleRoundedCornerRadius="20dp"
            app:navigationIcon="@drawable/bottomappbarnavigation" />
    <com.google.android.material.floatingactionbutton.FloatingActionButton
            android:id="@+id/fab"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_anchor="@id/bar"
            android:src="@drawable/add"
            app:tint="@android:color/white"
    />

</androidx.coordinatorlayout.widget.CoordinatorLayout>
coint arrondi du bottom app bar

L’espace entre le creux et le bouton flottant

L’attribut app:fabCradleMargin permet de définir l’espace entre le creux du bottom app bar et le bouton flottant

Espace minime

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <com.google.android.material.bottomappbar.BottomAppBar
        android:id="@+id/bar"
        android:layout_width="match_parent"
        android:layout_gravity="bottom"
        android:layout_height="wrap_content"
        android:backgroundTint="@color/colorPrimary"
        app:fabCradleMargin="5dp"
        app:navigationIcon="@drawable/bottomappbarnavigation" />
    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_anchor="@id/bar"
        android:src="@drawable/add"
        app:tint="@android:color/white"
        />

</androidx.coordinatorlayout.widget.CoordinatorLayout>

Espacement large

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <com.google.android.material.bottomappbar.BottomAppBar
        android:id="@+id/bar"
        android:layout_width="match_parent"
        android:layout_gravity="bottom"
        android:layout_height="wrap_content"
        android:backgroundTint="@color/colorPrimary"
        app:fabCradleMargin="20dp"
        app:navigationIcon="@drawable/bottomappbarnavigation" />
    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_anchor="@id/bar"
        android:src="@drawable/add"
        app:tint="@android:color/white"
        />

</androidx.coordinatorlayout.widget.CoordinatorLayout>

espace entre le bottomappbar et le bouton flottant

L’animation du changement du mode d’alignement du bouton flottant

L’attribut app:fabAnimationMode vous permet de définir l’animation lorsque le mode d’alignement du bouton flottant changera dynamiquement. Vous pouvez définir la valeur de cet attribut à scale ou slide

Mode d’animation définit à scale

Voici l’animation que vous pouvez obtenir lorsque le mode d’animation est défini à scale.

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

    <com.google.android.material.button.MaterialButton
            android:id="@+id/btn"
            android:text="Changer"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>

    <androidx.coordinatorlayout.widget.CoordinatorLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">

        <com.google.android.material.bottomappbar.BottomAppBar
                android:id="@+id/bar"
                android:layout_width="match_parent"
                android:layout_gravity="bottom"
                android:layout_height="wrap_content"
                android:backgroundTint="@color/colorPrimary"
                app:fabAlignmentMode="end"
                app:fabAnimationMode="scale"
                app:navigationIcon="@drawable/bottomappbarnavigation" />
        <com.google.android.material.floatingactionbutton.FloatingActionButton
                android:id="@+id/fab"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                app:layout_anchor="@id/bar"
                android:src="@drawable/add"
                app:tint="@android:color/white"
        />
    </androidx.coordinatorlayout.widget.CoordinatorLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
package com.example.bottomappbar

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import com.google.android.material.bottomappbar.BottomAppBar
import com.google.android.material.button.MaterialButton

class MainActivity : AppCompatActivity() {

    private lateinit var mBottomAppBar: BottomAppBar
    private lateinit var btn: MaterialButton
    private var changeMod: Boolean=false
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        mBottomAppBar=findViewById(R.id.bar)
        btn=findViewById(R.id.btn)
        btn.setOnClickListener {
            if(changeMod){
                changeMod=false
                mBottomAppBar.fabAlignmentMode=BottomAppBar.FAB_ALIGNMENT_MODE_CENTER
            }
            else{
               changeMod=true
                mBottomAppBar.fabAlignmentMode=BottomAppBar.FAB_ALIGNMENT_MODE_END
            }
        }


    }


}
package com.example.bottomappbarjava;

import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.coordinatorlayout.widget.CoordinatorLayout;

import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;

import com.google.android.material.bottomappbar.BottomAppBar;
import com.google.android.material.button.MaterialButton;
import com.google.android.material.floatingactionbutton.FloatingActionButton;

public class MainActivity extends AppCompatActivity {

   private BottomAppBar mBottomAppBar;
   private boolean changeMod=false;
   private MaterialButton btn;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mBottomAppBar=findViewById(R.id.bar);
        btn=findViewById(R.id.btn);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(changeMod){
                    changeMod=false;
                    mBottomAppBar.setFabAlignmentMode(BottomAppBar.FAB_ALIGNMENT_MODE_CENTER);
                }
                else{
                    changeMod=true;
                    mBottomAppBar.setFabAlignmentMode(BottomAppBar.FAB_ALIGNMENT_MODE_END);
                }
            }
        });
    }

}
bottom app bar animation mode scale

Mode d’animation définit à slide

Voici l’animation que vous pouvez obtenir lorsque le mode d’animation est défini à slide

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

    <com.google.android.material.button.MaterialButton
            android:id="@+id/btn"
            android:text="Changer"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>

    <androidx.coordinatorlayout.widget.CoordinatorLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">

        <com.google.android.material.bottomappbar.BottomAppBar
                android:id="@+id/bar"
                android:layout_width="match_parent"
                android:layout_gravity="bottom"
                android:layout_height="wrap_content"
                android:backgroundTint="@color/colorPrimary"
                app:fabAlignmentMode="end"
                app:fabAnimationMode="slide"
                app:navigationIcon="@drawable/bottomappbarnavigation" />
        <com.google.android.material.floatingactionbutton.FloatingActionButton
                android:id="@+id/fab"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                app:layout_anchor="@id/bar"
                android:src="@drawable/add"
                app:tint="@android:color/white"
        />
    </androidx.coordinatorlayout.widget.CoordinatorLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
package com.example.bottomappbar

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import com.google.android.material.bottomappbar.BottomAppBar
import com.google.android.material.button.MaterialButton

class MainActivity : AppCompatActivity() {

    private lateinit var mBottomAppBar: BottomAppBar
    private lateinit var btn: MaterialButton
    private var changeMod: Boolean=false
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        mBottomAppBar=findViewById(R.id.bar)
        btn=findViewById(R.id.btn)
        btn.setOnClickListener {
            if(changeMod){
                changeMod=false
                mBottomAppBar.fabAlignmentMode=BottomAppBar.FAB_ALIGNMENT_MODE_CENTER
            }
            else{
               changeMod=true
                mBottomAppBar.fabAlignmentMode=BottomAppBar.FAB_ALIGNMENT_MODE_END
            }
        }


    }


}
package com.example.bottomappbarjava;

import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.coordinatorlayout.widget.CoordinatorLayout;

import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;

import com.google.android.material.bottomappbar.BottomAppBar;
import com.google.android.material.button.MaterialButton;
import com.google.android.material.floatingactionbutton.FloatingActionButton;

public class MainActivity extends AppCompatActivity {

   private BottomAppBar mBottomAppBar;
   private boolean changeMod=false;
   private MaterialButton btn;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mBottomAppBar=findViewById(R.id.bar);
        btn=findViewById(R.id.btn);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(changeMod){
                    changeMod=false;
                    mBottomAppBar.setFabAlignmentMode(BottomAppBar.FAB_ALIGNMENT_MODE_CENTER);
                }
                else{
                    changeMod=true;
                    mBottomAppBar.setFabAlignmentMode(BottomAppBar.FAB_ALIGNMENT_MODE_END);
                }
            }
        });
    }

}

bottom app bar animation mode slide

Comportement lors du scroll

L’attribut app:hideOnScroll vous permet de définir comment vous souhaitez que le bottom app bar réagisse lorsque la vue contient un élément scrollable(Recyclerview ou NestedScrollView).Il faut savoir que que le contenu scrollable et le bottom app bar doivent être placé dans un CoordinatorLayout.

Cet attribut peut prendre deux valeur :true et false. Si la valeur définie est true,le bottom app bar va se cacher lorsque l’utilisateur scroll le contenu vers le haut.

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

    <androidx.coordinatorlayout.widget.CoordinatorLayout
            android:layout_width="match_parent"

            android:layout_height="match_parent">
        <androidx.core.widget.NestedScrollView
                android:layout_width="match_parent"
                android:paddingRight="16dp"
                android:paddingLeft="16dp"
                android:layout_height="match_parent">

            <LinearLayout
                android:layout_width="match_parent"
                android:backgroundTint="#f1f1f1"
                android:orientation="vertical"
                android:layout_height="match_parent">
                <androidx.cardview.widget.CardView
                        android:layout_width="match_parent"
                        android:layout_margin="8dp"
                        android:layout_height="wrap_content"
                        >
                    <LinearLayout
                            android:layout_width="match_parent"
                            android:orientation="vertical"
                            android:padding="8dp"
                            android:layout_height="wrap_content">
                        <TextView
                                android:text="Contenu scrollable"
                                android:textStyle="bold"
                                android:textSize="16sp"
                                android:textColor="#000000"
                                android:layout_width="match_parent"
                                android:layout_height="wrap_content" />
                        <TextView
                                android:text="Contrairement à une opinion répandue, le Lorem Ipsum n'est pas simplement du texte aléatoire. Il trouve ses racines dans une oeuvre de la littérature latine classique datant de 45 av. J.-C., le rendant vieux de 2000 ans. Un professeur du Hampden-Sydney College, en Virginie, s'est intéressé à un des mots latins les plus obscurs, consectetur, extrai"
                                android:textSize="14sp"
                                android:layout_width="match_parent"
                                android:layout_height="wrap_content" />
                    </LinearLayout>
                </androidx.cardview.widget.CardView>
                <androidx.cardview.widget.CardView
                        android:layout_width="match_parent"
                        android:layout_margin="8dp"
                        android:layout_height="wrap_content"
                >
                    <LinearLayout
                            android:layout_width="match_parent"
                            android:orientation="vertical"
                            android:padding="8dp"
                            android:layout_height="wrap_content">
                        <TextView
                                android:text="Contenu scrollable"
                                android:textStyle="bold"
                                android:textSize="16sp"
                                android:textColor="#000000"
                                android:layout_width="match_parent"
                                android:layout_height="wrap_content" />
                        <TextView
                                android:text="Contrairement à une opinion répandue, le Lorem Ipsum n'est pas simplement du texte aléatoire. Il trouve ses racines dans une oeuvre de la littérature latine classique datant de 45 av. J.-C., le rendant vieux de 2000 ans. Un professeur du Hampden-Sydney College, en Virginie, s'est intéressé à un des mots latins les plus obscurs, consectetur, extrai"
                                android:textSize="14sp"
                                android:layout_width="match_parent"
                                android:layout_height="wrap_content" />
                    </LinearLayout>
                </androidx.cardview.widget.CardView>
                <androidx.cardview.widget.CardView
                        android:layout_width="match_parent"
                        android:layout_margin="8dp"
                        android:layout_height="wrap_content"
                >
                    <LinearLayout
                            android:layout_width="match_parent"
                            android:orientation="vertical"
                            android:padding="8dp"
                            android:layout_height="wrap_content">
                        <TextView
                                android:text="Contenu scrollable"
                                android:textStyle="bold"
                                android:textSize="16sp"
                                android:textColor="#000000"
                                android:layout_width="match_parent"
                                android:layout_height="wrap_content" />
                        <TextView
                                android:text="Contrairement à une opinion répandue, le Lorem Ipsum n'est pas simplement du texte aléatoire. Il trouve ses racines dans une oeuvre de la littérature latine classique datant de 45 av. J.-C., le rendant vieux de 2000 ans. Un professeur du Hampden-Sydney College, en Virginie, s'est intéressé à un des mots latins les plus obscurs, consectetur, extrai"
                                android:textSize="14sp"
                                android:layout_width="match_parent"
                                android:layout_height="wrap_content" />
                    </LinearLayout>
                </androidx.cardview.widget.CardView>
                <androidx.cardview.widget.CardView
                        android:layout_width="match_parent"
                        android:layout_margin="8dp"
                        android:layout_height="wrap_content"
                >
                    <LinearLayout
                            android:layout_width="match_parent"
                            android:orientation="vertical"
                            android:padding="8dp"
                            android:layout_height="wrap_content">
                        <TextView
                                android:text="Contenu scrollable"
                                android:textStyle="bold"
                                android:textSize="16sp"
                                android:textColor="#000000"
                                android:layout_width="match_parent"
                                android:layout_height="wrap_content" />
                        <TextView
                                android:text="Contrairement à une opinion répandue, le Lorem Ipsum n'est pas simplement du texte aléatoire. Il trouve ses racines dans une oeuvre de la littérature latine classique datant de 45 av. J.-C., le rendant vieux de 2000 ans. Un professeur du Hampden-Sydney College, en Virginie, s'est intéressé à un des mots latins les plus obscurs, consectetur, extrai"
                                android:textSize="14sp"
                                android:layout_width="match_parent"
                                android:layout_height="wrap_content" />
                    </LinearLayout>
                </androidx.cardview.widget.CardView>
                <androidx.cardview.widget.CardView
                        android:layout_width="match_parent"
                        android:layout_margin="8dp"
                        android:layout_height="wrap_content"
                >
                    <LinearLayout
                            android:layout_width="match_parent"
                            android:orientation="vertical"
                            android:padding="8dp"
                            android:layout_height="wrap_content">
                        <TextView
                                android:text="Contenu scrollable"
                                android:textStyle="bold"
                                android:textSize="16sp"
                                android:textColor="#000000"
                                android:layout_width="match_parent"
                                android:layout_height="wrap_content" />
                        <TextView
                                android:text="Contrairement à une opinion répandue, le Lorem Ipsum n'est pas simplement du texte aléatoire. Il trouve ses racines dans une oeuvre de la littérature latine classique datant de 45 av. J.-C., le rendant vieux de 2000 ans. Un professeur du Hampden-Sydney College, en Virginie, s'est intéressé à un des mots latins les plus obscurs, consectetur, extrai"
                                android:textSize="14sp"
                                android:layout_width="match_parent"
                                android:layout_height="wrap_content" />
                    </LinearLayout>
                </androidx.cardview.widget.CardView>
                <androidx.cardview.widget.CardView
                        android:layout_width="match_parent"
                        android:layout_margin="8dp"
                        android:layout_height="wrap_content"
                >
                    <LinearLayout
                            android:layout_width="match_parent"
                            android:orientation="vertical"
                            android:padding="8dp"
                            android:layout_height="wrap_content">
                        <TextView
                                android:text="Contenu scrollable"
                                android:textStyle="bold"
                                android:textSize="16sp"
                                android:textColor="#000000"
                                android:layout_width="match_parent"
                                android:layout_height="wrap_content" />
                        <TextView
                                android:text="Contrairement à une opinion répandue, le Lorem Ipsum n'est pas simplement du texte aléatoire. Il trouve ses racines dans une oeuvre de la littérature latine classique datant de 45 av. J.-C., le rendant vieux de 2000 ans. Un professeur du Hampden-Sydney College, en Virginie, s'est intéressé à un des mots latins les plus obscurs, consectetur, extrai"
                                android:textSize="14sp"
                                android:layout_width="match_parent"
                                android:layout_height="wrap_content" />
                    </LinearLayout>
                </androidx.cardview.widget.CardView>
                <androidx.cardview.widget.CardView
                        android:layout_width="match_parent"
                        android:layout_margin="8dp"
                        android:layout_height="wrap_content"
                >
                    <LinearLayout
                            android:layout_width="match_parent"
                            android:orientation="vertical"
                            android:padding="8dp"
                            android:layout_height="wrap_content">
                        <TextView
                                android:text="Contenu scrollable"
                                android:textStyle="bold"
                                android:textSize="16sp"
                                android:textColor="#000000"
                                android:layout_width="match_parent"
                                android:layout_height="wrap_content" />
                        <TextView
                                android:text="Contrairement à une opinion répandue, le Lorem Ipsum n'est pas simplement du texte aléatoire. Il trouve ses racines dans une oeuvre de la littérature latine classique datant de 45 av. J.-C., le rendant vieux de 2000 ans. Un professeur du Hampden-Sydney College, en Virginie, s'est intéressé à un des mots latins les plus obscurs, consectetur, extrai"
                                android:textSize="14sp"
                                android:layout_width="match_parent"
                                android:layout_height="wrap_content" />
                    </LinearLayout>
                </androidx.cardview.widget.CardView>
                <androidx.cardview.widget.CardView
                        android:layout_width="match_parent"
                        android:layout_margin="8dp"
                        android:layout_height="wrap_content"
                >
                    <LinearLayout
                            android:layout_width="match_parent"
                            android:orientation="vertical"
                            android:padding="8dp"
                            android:layout_height="wrap_content">
                        <TextView
                                android:text="Contenu scrollable"
                                android:textStyle="bold"
                                android:textSize="16sp"
                                android:textColor="#000000"
                                android:layout_width="match_parent"
                                android:layout_height="wrap_content" />
                        <TextView
                                android:text="Contrairement à une opinion répandue, le Lorem Ipsum n'est pas simplement du texte aléatoire. Il trouve ses racines dans une oeuvre de la littérature latine classique datant de 45 av. J.-C., le rendant vieux de 2000 ans. Un professeur du Hampden-Sydney College, en Virginie, s'est intéressé à un des mots latins les plus obscurs, consectetur, extrai"
                                android:textSize="14sp"
                                android:layout_width="match_parent"
                                android:layout_height="wrap_content" />
                    </LinearLayout>
                </androidx.cardview.widget.CardView>
                <androidx.cardview.widget.CardView
                        android:layout_width="match_parent"
                        android:layout_margin="8dp"
                        android:layout_height="wrap_content"
                >
                    <LinearLayout
                            android:layout_width="match_parent"
                            android:orientation="vertical"
                            android:padding="8dp"
                            android:layout_height="wrap_content">
                        <TextView
                                android:text="Contenu scrollable"
                                android:textStyle="bold"
                                android:textSize="16sp"
                                android:textColor="#000000"
                                android:layout_width="match_parent"
                                android:layout_height="wrap_content" />
                        <TextView
                                android:text="Contrairement à une opinion répandue, le Lorem Ipsum n'est pas simplement du texte aléatoire. Il trouve ses racines dans une oeuvre de la littérature latine classique datant de 45 av. J.-C., le rendant vieux de 2000 ans. Un professeur du Hampden-Sydney College, en Virginie, s'est intéressé à un des mots latins les plus obscurs, consectetur, extrai"
                                android:textSize="14sp"
                                android:layout_width="match_parent"
                                android:layout_height="wrap_content" />
                    </LinearLayout>
                </androidx.cardview.widget.CardView>

            </LinearLayout>
        </androidx.core.widget.NestedScrollView>

        <com.google.android.material.bottomappbar.BottomAppBar
                android:id="@+id/bar"
                android:layout_width="match_parent"
                android:layout_gravity="bottom"
                android:layout_height="wrap_content"
                android:backgroundTint="@color/colorPrimary"
                app:fabAlignmentMode="end"
                app:hideOnScroll="true"
                app:navigationIcon="@drawable/bottomappbarnavigation" />
        <com.google.android.material.floatingactionbutton.FloatingActionButton
                android:id="@+id/fab"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                app:layout_anchor="@id/bar"
                android:src="@drawable/add"
                app:tint="@android:color/white"
        />
    </androidx.coordinatorlayout.widget.CoordinatorLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
bottom app bar animation scroll

L’espace entre le creux du botttom app bar et le bouton flottant

L’attribut app:fabCradleMargin vous permet d’ajutser l’espace entre le bouton flottant et le creux du bottom app bar

Large espace

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

    <com.google.android.material.bottomappbar.BottomAppBar
            android:id="@+id/bar"
            android:layout_width="match_parent"
            android:layout_gravity="bottom"
            android:layout_height="wrap_content"
            android:backgroundTint="@color/colorPrimary"
            app:fabCradleMargin="20dp"
            app:navigationIcon="@drawable/bottomappbarnavigation" />
    <com.google.android.material.floatingactionbutton.FloatingActionButton
            android:id="@+id/fab"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_anchor="@id/bar"
            android:src="@drawable/add"
            app:tint="@android:color/white"
    />

</androidx.coordinatorlayout.widget.CoordinatorLayout>

Espace minime

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

    <com.google.android.material.bottomappbar.BottomAppBar
            android:id="@+id/bar"
            android:layout_width="match_parent"
            android:layout_gravity="bottom"
            android:layout_height="wrap_content"
            android:backgroundTint="@color/colorPrimary"
            app:fabCradleMargin="5dp"
            app:navigationIcon="@drawable/bottomappbarnavigation" />
    <com.google.android.material.floatingactionbutton.FloatingActionButton
            android:id="@+id/fab"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_anchor="@id/bar"
            android:src="@drawable/add"
            app:tint="@android:color/white"
    />

</androidx.coordinatorlayout.widget.CoordinatorLayout>

Créer un thème de forme sur le composant BottomAppBar

Si c’est votre premier tutoriel sur le material design 2, vous devez lire ce tutoriel sur comment créer des thermes de formes.

Nous allons créer une nouvelle forme(forme coupé au lieu de la forme arrondi) pour le bouton flottant et le creux du bottomAppBar grâce au classe CutCornerTreatment et MaterialShapeDrawable.

Creer une forme au bouton flottant

Pour donner une forme coupé au bouton flottant procédez comme suite

Etape1:Crer un style ShapeOverlay comme suit.

 <style name="ShapeOverlay.MyFloatingActionButton"  parent="">
        <item name="cornerFamily">cut</item>
        <item name="cornerSize">8dp</item>
        
  </style>

Etape 2:Appliquez ensuite le style au bouton flottant comme suit

 <com.google.android.material.floatingactionbutton.FloatingActionButton
     ....         
     app:shapeAppearance="@style/ShapeOverlay.MyFloatingActionButton"
     ....   
    />

le fichier layout doit doit se présenter maintenant comme suit

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

    <com.google.android.material.bottomappbar.BottomAppBar
            android:id="@+id/bar"
            android:layout_width="match_parent"
            android:layout_gravity="bottom"
            android:layout_height="wrap_content"
            app:navigationIcon="@drawable/bottomappbarnavigation" />
    <com.google.android.material.floatingactionbutton.FloatingActionButton
            android:id="@+id/fab"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_anchor="@id/bar"
            android:src="@drawable/add"
            app:shapeAppearance="@style/ShapeOverlay.MyFloatingActionButton"
            app:tint="@android:color/white"
    />

</androidx.coordinatorlayout.widget.CoordinatorLayout>

Résultat:

bottom bar avec bouton flottant coupé

Créer une forme au creux du bottomAppbar

Pour creer une forme au creux du bottom app bar, nous allons utiliser le BottomAppBarCutCornersTopEdge fourni par Google .

package com.example.bottomappbar

import android.annotation.SuppressLint
import com.google.android.material.bottomappbar.BottomAppBarTopEdgeTreatment
import com.google.android.material.shape.ShapePath

class BottomAppBarCutCornersTopEdge internal constructor(
    private val fabMargin: Float,
    roundedCornerRadius: Float,
    private val cradleVerticalOffset: Float
) : BottomAppBarTopEdgeTreatment(fabMargin, roundedCornerRadius, cradleVerticalOffset) {

    @SuppressLint("RestrictedApi")
    override fun getEdgePath(
        length: Float,
        center: Float,
        interpolation: Float,
        shapePath: ShapePath
    ) {
        val fabDiameter = fabDiameter
        if (fabDiameter == 0f) {
            shapePath.lineTo(length, 0f)
            return
        }

        val diamondSize = fabDiameter / 2f
        val middle = center + horizontalOffset

        val verticalOffsetRatio = cradleVerticalOffset / diamondSize
        if (verticalOffsetRatio >= 1.0f) {
            shapePath.lineTo(length, 0f)
            return
        }

        shapePath.lineTo(middle - (fabMargin + diamondSize - cradleVerticalOffset), 0f)

        shapePath.lineTo(middle, (diamondSize - cradleVerticalOffset + fabMargin) * interpolation)

        shapePath.lineTo(middle + (fabMargin + diamondSize - cradleVerticalOffset), 0f)

        shapePath.lineTo(length, 0f)
    }
}
package com.example.bottomappbar.cut;

import android.annotation.SuppressLint;
import com.google.android.material.bottomappbar.BottomAppBarTopEdgeTreatment;
import com.google.android.material.shape.ShapePath;

public class BottomAppBarCutCornersTopEdge extends BottomAppBarTopEdgeTreatment {
    private final float fabMargin;
    private final float cradleVerticalOffset;

    BottomAppBarCutCornersTopEdge(
            float fabMargin, float roundedCornerRadius, float cradleVerticalOffset) {
        super(fabMargin, roundedCornerRadius, cradleVerticalOffset);
        this.fabMargin = fabMargin;
        this.cradleVerticalOffset = cradleVerticalOffset;
    }

    @Override
    @SuppressLint("RestrictedApi")
    public void getEdgePath(float length, float center, float interpolation, ShapePath shapePath) {
        float fabDiameter = getFabDiameter();
        if (fabDiameter == 0) {
            shapePath.lineTo(length, 0);
            return;
        }

        float diamondSize = fabDiameter / 2f;
        float middle = center + getHorizontalOffset();

        float verticalOffsetRatio = cradleVerticalOffset / diamondSize;
        if (verticalOffsetRatio >= 1.0f) {
            shapePath.lineTo(length, 0);
            return;
        }

        shapePath.lineTo(middle - (fabMargin + diamondSize - cradleVerticalOffset), 0);

        shapePath.lineTo(middle, (diamondSize - cradleVerticalOffset + fabMargin) * interpolation);

        shapePath.lineTo(middle + (fabMargin + diamondSize - cradleVerticalOffset), 0);

        shapePath.lineTo(length, 0);
    }
}

Ensuite construisez le ShapeAppearanceMode et définissez le MaterialShappedrawable comme suit

package com.example.bottomappbar

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import com.google.android.material.bottomappbar.BottomAppBar
import com.google.android.material.button.MaterialButton
import com.google.android.material.shape.MaterialShapeDrawable

class MainActivity : AppCompatActivity() {

    private lateinit var mBottomAppBar: BottomAppBar

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        mBottomAppBar=findViewById(R.id.bar)
        val topEdget:BottomAppBarCutCornersTopEdge= BottomAppBarCutCornersTopEdge(mBottomAppBar.fabCradleMargin,
            mBottomAppBar.fabCradleRoundedCornerRadius,
            mBottomAppBar.cradleVerticalOffset)
        val materialShapeDrawable= mBottomAppBar.background as MaterialShapeDrawable
        materialShapeDrawable.shapeAppearanceModel= materialShapeDrawable.shapeAppearanceModel
                .toBuilder()
                .setTopEdge(topEdget)
                .build()



    }


}
package com.example.bottomappbarjava;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;


import com.google.android.material.bottomappbar.BottomAppBar;
import com.google.android.material.shape.MaterialShapeDrawable;


public class MainActivity extends AppCompatActivity {

   private BottomAppBar mBottomAppBar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mBottomAppBar=findViewById(R.id.bar);
       BottomAppBarCutCornersTopEdge topEdget=new BottomAppBarCutCornersTopEdge(mBottomAppBar.getFabCradleMargin(),
               mBottomAppBar.getFabCradleRoundedCornerRadius(),
               mBottomAppBar.getCradleVerticalOffset());

        MaterialShapeDrawable materialShapeDrawable =(MaterialShapeDrawable)mBottomAppBar.getBackground();
        materialShapeDrawable.setShapeAppearanceModel(materialShapeDrawable.getShapeAppearanceModel()
                .toBuilder()
                .setTopEdge(topEdget)
                .build()
                );
    }

}

Voici le fichier layout

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

    <com.google.android.material.bottomappbar.BottomAppBar
            android:id="@+id/bar"
            android:layout_width="match_parent"
            android:layout_gravity="bottom"
            android:layout_height="wrap_content"
            app:fabCradleMargin="8dp"
            android:backgroundTint="@color/colorPrimary"
            app:navigationIcon="@drawable/bottomappbarnavigation" />
    <com.google.android.material.floatingactionbutton.FloatingActionButton
            android:id="@+id/fab"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_anchor="@id/bar"
            android:src="@drawable/add"
            app:shapeAppearance="@style/ShapeOverlay.MyFloatingActionButton"
            app:tint="@android:color/white"
    />

</androidx.coordinatorlayout.widget.CoordinatorLayout>

Résultat

bottom app bar avec coté haut coupé

Autres exemple:Ajoutez un le menu au bottomappbar avec l’attribut app:menu= »@menu/menu » et dans le menu ajoutez l’attribut app:showAsAction= »ifRoom » pour l’affichage des icons. L’image suivante montre ce que vous devez obtenir

bottom app bar coupé et affichage des icon à gauche

Pour afficher les items de menu à gauche définissez la valeur de l’attribut app:fabAlignmentMode= »end » du bottom app bar à end. L’image suivant montre ce que vous devez obtenir

bottom app bar coupé et affichage des icons à gauche

Autres ressources

https://material.io/components/app-bars-bottom/

https://github.com/material-components/material-components-android/blob/master/lib/java/com/google/android/material/bottomappbar/BottomAppBar.java

https://developer.android.com/reference/com/google/android/material/bottomappbar/BottomAppBar

Conclusion

Nous sommes à la fin de ce tutoriel sur le bottom app bar.J’espère que ce tutoriel vous aidera à utiliser le composant bottom app bar.A bientôt pour un nouveau tutoriel.


Laisser un commentaire

Résoudre : *
3 ⁄ 3 =


%d