
In questa guida scoprirai come usare CoordinatorLayout Android per creare interfacce dinamiche in stile Material Design, in cui toolbar, contenuti e pannelli reagiscono in modo coordinato alle azioni dell’utente. Questo CoordinatorLayout Android tutorial ti mostrerà cos’è questo layout avanzato, a cosa serve e quando conviene introdurlo nei tuoi progetti. Tutti gli esempi sono sviluppati in Java utilizzando Android Studio, così potrai integrarli facilmente nelle tue app esistenti. Continua a leggere per imparare passo dopo passo come ottenere effetti professionali con il minimo sforzo.
Cos’è CoordinatorLayout Android
CoordinatorLayout è un layout avanzato di Material Design usato quando più viste devono reagire insieme; in particolare, è utile per gestire toolbar a scomparsa, Snackbar animate e BottomSheet. Inoltre, le viste figlie comunicano tramite l’attributo app:layout_behavior, che quindi assegna un comportamento preciso in risposta alle azioni dell’utente e, in questo modo, coordina le loro interazioni.
L’elemento chiave di CoordinatorLayout è l’attributo app:layout_behavior, che assegna un comportamento specifico a ogni vista figlia. Grazie a questo attributo, la vista può comunicare con il layout genitore e con le altre viste figlie, coordinando reazioni alle azioni dell’utente. Ad esempio, la proprietà @string/appbar_scrolling_view_behavior dice a una vista di adattarsi quando la AppBarLayout scorre verso l’alto.
CoordinatorLayout è preferibile a ConstraintLayout o LinearLayout quando il tuo progetto richiede comportamenti coordinati tra viste. Mentre ConstraintLayout eccelle nel creare layout complessi con vincoli relazionali e LinearLayout è ideale per strutture semplici e lineari, CoordinatorLayout brilla quando hai toolbar a scomparsa, Snackbar che si spostano sopra un FloatingActionButton, o BottomSheet che interagiscono con il resto dell’interfaccia. Quindi, scegli CoordinatorLayout se il tuo design richiede animazioni e comportamenti dinamici tra elementi.
Rispetto a un semplice FrameLayout, che si limita a impilare le viste una sopra l’altra senza alcuna logica di coordinamento, CoordinatorLayout Android aggiunge un livello di intelligenza: ogni vista può reagire allo scroll, ai tocchi o ai cambiamenti di stato delle altre. Usa FrameLayout per container statici e sovrapposizioni semplici; scegli CoordinatorLayout Android quando vuoi Toolbar che scompaiono allo scroll, BottomSheet che emergono da sotto il contenuto o FloatingActionButton che si spostano automaticamente per non coprire una Snackbar.
Esempio 1: Toolbar con CoordinatorLayout Android
In questo esempio, sostituiamo la ActionBar predefinita con una Toolbar personalizzata tramite il metodo setSupportActionBar(). Perché funzioni, il tema dell’app deve usare una variante con suffisso NoActionBar. Inoltre, questa personalizzazione consente maggiore flessibilità nel design della barra di navigazione.
themes.xml
<style name="Theme.MyApplication" parent="Theme.MaterialComponents.DayNight.NoActionBar">
<!-- altri attributi del tema -->
</style>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.appcompat.widget.Toolbar
android:id="@+id/app_bar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize" />
</com.google.android.material.appbar.AppBarLayout>
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<!-- Contenuto scrollabile qui -->
</androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
MainActivity.java
package com.example.coordinatorLayout;
import androidx.appcompat.widget.Toolbar;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.app_bar);
setSupportActionBar(toolbar);
}
}
Esempio 2: BottomSheet con CoordinatorLayout Android tutorial
Un BottomSheet è un pannello che si apre dal bordo inferiore dello schermo. Di conseguenza, rappresenta un elemento fondamentale del Material Design. Si configura aggiungendo l’attributo app:layout_behavior="@string/bottom_sheet_behavior" nel layout e usando la classe BottomSheetBehavior nel codice Java.
activity_main.xml (con BottomSheet)
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<RelativeLayout
android:id="@+id/bottom_sheet"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#CCBBFF"
app:layout_behavior="@string/bottom_sheet_behavior"
app:behavior_peekHeight="100dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="BottomSheet"
android:textColor="#B30DAD"
android:textSize="30sp" />
</RelativeLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
MainActivity.java (con BottomSheet)
package com.example.coordinatorLayout;
import android.view.View;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import com.google.android.material.bottomsheet.BottomSheetBehavior;
public class MainActivity extends AppCompatActivity {
private BottomSheetBehavior<View> bottomSheetBehavior;
private View bottomSheet;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bottomSheet = findViewById(R.id.bottom_sheet);
bottomSheetBehavior = BottomSheetBehavior.from(bottomSheet);
// Espandi o collassa il BottomSheet programmaticamente
// bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
// bottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
}
}
CoordinatorLayout Android tutorial è uno strumento essenziale per realizzare interfacce Material Design moderne e reattive. I casi d’uso più comuni includono toolbar collabibili, BottomSheet draggable, Snackbar coordinati e qualsiasi situazione in cui più viste devono reagire insieme alle azioni dell’utente. Se desideri approfondire ulteriormente, consulta la documentazione ufficiale di CoordinatorLayout e i design guidelines di Material Design.
AppBarLayout Android con Toolbar collassabile in CoordinatorLayout Android
Uno degli utilizzi più diffusi di CoordinatorLayout Android è la creazione di una Toolbar collassabile che scompare o si riduce quando l’utente effettua lo scroll del contenuto. Questo pattern è gestito tramite AppBarLayout e CollapsingToolbarLayout. Di seguito trovi un esempio completo in XML per ottenere una AppBarLayout Android con immagine di copertina e titolo che si riduce durante lo scroll.
activity_collapsing_toolbar.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".CollapsingToolbarActivity">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="300dp"
android:fitsSystemWindows="true">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:id="@+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleMarginStart="48dp"
app:title="CoordinatorLayout Android">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:src="@drawable/header_image"
android:fitsSystemWindows="true"
app:layout_collapseMode="parallax" />
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin" />
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>
<androidx.core.widget.NestedScrollView
android:id="@+id/scroll_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Contenuto lungo per testare lo scroll coordinato con AppBarLayout Android e CollapsingToolbarLayout. Aggiungi qui il testo della tua guida o della tua schermata di dettaglio." />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
CollapsingToolbarActivity.java
package com.example.coordinatorLayout;
import android.os.Bundle;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import com.google.android.material.appbar.CollapsingToolbarLayout;
public class CollapsingToolbarActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_collapsing_toolbar);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
CollapsingToolbarLayout collapsingToolbarLayout = findViewById(R.id.collapsing_toolbar);
collapsingToolbarLayout.setTitle("CoordinatorLayout Android");
}
}
BottomSheet modale e persistente con CoordinatorLayout Android
Con CoordinatorLayout Java puoi gestire sia BottomSheet persistenti (ancorati nel layout, come nell’esempio precedente) sia BottomSheet modali che compaiono sopra l’interfaccia corrente. Qui sotto trovi un esempio completo per entrambi i casi, sempre in Java.
BottomSheet persistente (layout + Java)
<androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="@+id/content_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<LinearLayout
android:id="@+id/persistent_bottom_sheet"
android:layout_width="match_parent"
android:layout_height="300dp"
android:orientation="vertical"
android:padding="16dp"
app:layout_behavior="@string/bottom_sheet_behavior"
app:behavior_peekHeight="80dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="BottomSheet persistente" />
</LinearLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
package com.example.coordinatorLayout;
import android.os.Bundle;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import com.google.android.material.bottomsheet.BottomSheetBehavior;
public class PersistentBottomSheetActivity extends AppCompatActivity {
private BottomSheetBehavior<View> bottomSheetBehavior;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_persistent_bottom_sheet);
View bottomSheet = findViewById(R.id.persistent_bottom_sheet);
bottomSheetBehavior = BottomSheetBehavior.from(bottomSheet);
bottomSheetBehavior.addBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
@Override
public void onStateChanged(@NonNull View bottomSheet, int newState) {
// Gestisci i cambi di stato: COLLAPSED, EXPANDED, HIDDEN, ecc.
}
@Override
public void onSlide(@NonNull View bottomSheet, float slideOffset) {
// Aggiorna la UI in base allo slideOffset, se necessario
}
});
}
}
BottomSheet modale (BottomSheetDialogFragment)
package com.example.coordinatorLayout;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
public class ExampleModalBottomSheet extends BottomSheetDialogFragment {
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater,
@Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.modal_bottom_sheet_content, container, false);
}
}
package com.example.coordinatorLayout;
import android.os.Bundle;
import android.view.View;
import androidx.appcompat.app.AppCompatActivity;
import com.google.android.material.button.MaterialButton;
public class ModalBottomSheetActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_modal_bottom_sheet);
MaterialButton openBottomSheetButton = findViewById(R.id.open_bottom_sheet_button);
openBottomSheetButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ExampleModalBottomSheet bottomSheet = new ExampleModalBottomSheet();
bottomSheet.show(getSupportFragmentManager(), "ModalBottomSheet");
}
});
}
}
FloatingActionButton e Snackbar con CoordinatorLayout Android
Un altro pattern tipico di CoordinatorLayout Android è il FloatingActionButton (FAB) che si sposta automaticamente quando compare una Snackbar, per non essere coperto visivamente. Il layout seguente mostra come dichiarare il FAB all’interno del CoordinatorLayout e come mostrare una Snackbar da codice Java.
activity_fab_snackbar.xml
<androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/root_coordinator"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/text_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Esempio CoordinatorLayout Java con FAB e Snackbar" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="16dp"
app:srcCompat="@drawable/ic_add" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
FabSnackbarActivity.java
package com.example.coordinatorLayout;
import android.os.Bundle;
import android.view.View;
import androidx.appcompat.app.AppCompatActivity;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.snackbar.Snackbar;
public class FabSnackbarActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fab_snackbar);
final View rootCoordinator = findViewById(R.id.root_coordinator);
FloatingActionButton fab = findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Snackbar.make(rootCoordinator,
"Azione eseguita con CoordinatorLayout Android",
Snackbar.LENGTH_LONG)
.setAction("Annulla", new View.OnClickListener() {
@Override
public void onClick(View v) {
// Gestisci il click su "Annulla"
}
})
.show();
}
});
}
}
Behavior personalizzato in CoordinatorLayout Android
In questo CoordinatorLayout Android tutorial, il vero punto di forza di CoordinatorLayout Android è la possibilità di definire Behavior personalizzati, cioè classi Java che descrivono come una vista deve reagire ai cambiamenti di un’altra (scroll, movimento, comparsa/scomparsa). In questo esempio creiamo un Behavior che sposta una View verso l’alto quando una AppBarLayout viene collassata.
MyCustomBehavior.java
package com.example.coordinatorLayout;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.coordinatorlayout.widget.CoordinatorLayout;
import com.google.android.material.appbar.AppBarLayout;
public class MyCustomBehavior extends CoordinatorLayout.Behavior<View> {
public MyCustomBehavior() {
super();
}
public MyCustomBehavior(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean layoutDependsOn(@NonNull CoordinatorLayout parent,
@NonNull View child,
@NonNull View dependency) {
return dependency instanceof AppBarLayout;
}
@Override
public boolean onDependentViewChanged(@NonNull CoordinatorLayout parent,
@NonNull View child,
@NonNull View dependency) {
float ratio = -dependency.getY() / dependency.getHeight();
float translation = ratio * child.getHeight();
child.setTranslationY(-translation);
return true;
}
}
Utilizzo nel layout XML
<androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="200dp" />
<View
android:id="@+id/animated_view"
android:layout_width="match_parent"
android:layout_height="56dp"
android:layout_gravity="bottom"
android:background="@android:color/holo_blue_light"
app:layout_behavior="com.example.coordinatorLayout.MyCustomBehavior" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
NestedScrollView con CoordinatorLayout: scroll coordinato
Per ottenere uno scroll coordinato tra contenuto e AppBarLayout Android devi usare una vista che supporti lo scrolling annidato, come NestedScrollView o RecyclerView, insieme al Behavior @string/appbar_scrolling_view_behavior. Questo consente a CoordinatorLayout Android di ricevere gli eventi di scroll e aggiornare la Toolbar o altri componenti. Seguendo questo CoordinatorLayout Android tutorial, potrai implementare scroll coordinati fluidi in qualsiasi progetto.
Esempio completo con NestedScrollView
<androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar_nested"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize" />
</com.google.android.material.appbar.AppBarLayout>
<androidx.core.widget.NestedScrollView
android:id="@+id/nested_scroll"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Testo lungo per verificare lo scroll coordinato con CoordinatorLayout Android e NestedScrollView" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
Proprietà principali di BottomSheetBehavior in CoordinatorLayout Android
| Stato | Descrizione |
|---|---|
STATE_COLLAPSED | Pannello collassato, visibile solo per l’altezza di peekHeight |
STATE_EXPANDED | Pannello completamente espanso |
STATE_HIDDEN | Pannello completamente nascosto (richiede setHideable(true)) |
STATE_DRAGGING | L’utente sta trascinando il pannello |
STATE_SETTLING | Il pannello sta raggiungendo uno stato finale dopo il trascinamento |
Dipendenza Gradle
implementation 'com.google.android.material:material:1.9.0'
Articoli correlati
Articoli correlati
FAQ su CoordinatorLayout Android
- CoordinatorLayout vs FrameLayout?
UsaFrameLayoutquando ti serve solo un contenitore semplice per sovrapporre viste senza interazioni complesse. Scegli CoordinatorLayout Android quando hai bisogno di Behavior, Toolbar collassabili, Snackbar che spostano il FloatingActionButton o BottomSheet che interagiscono con il contenuto. - Come aggiungere un BottomSheet al CoordinatorLayout?
Dichiara una vista (es.LinearLayoutoFrameLayout) all’interno diCoordinatorLayoute impostaapp:layout_behavior="@string/bottom_sheet_behavior". In Java recupera la vista e usaBottomSheetBehavior.from(view)per controllarne lo stato (ESPANSA, COLLASSATA, NASCOSTA). - Come fare la Toolbar che scompare allo scroll?
UtilizzaAppBarLayout AndroidconCollapsingToolbarLayout, aggiungi il flagapp:layout_scrollFlags="scroll|exitUntilCollapsed"e racchiudi il contenuto in unaNestedScrollViewoRecyclerViewconapp:layout_behavior="@string/appbar_scrolling_view_behavior". In questo modo lo scroll coordina il movimento della Toolbar. - Posso usare CoordinatorLayout con RecyclerView invece di NestedScrollView?
Sì, CoordinatorLayout Android funziona perfettamente conRecyclerView. È sufficiente che la RecyclerView sia figlia del CoordinatorLayout e che abbia impostatoapp:layout_behavior="@string/appbar_scrolling_view_behavior"per coordinare lo scroll con AppBarLayout. - Quando ha senso creare un Behavior personalizzato?
Crea un Behavior custom quando due o più viste devono reagire tra loro in modo non coperto dai Behavior standard (scroll della Toolbar, BottomSheet, Snackbar). Ad esempio, per spostare un banner promozionale in base allo scroll, nascondere/mostrare un pulsante in sincronia con l’AppBarLayout o creare animazioni personalizzate guidate dallo scroll.