Stack — cos'è, livelli e posizionamento in Flutter

Autore: IT Sectr Pubblicato: 2026-02-24 Tempo di lettura: 6 min

Scopri cos'è Stack in Flutter — un widget che posiziona gli elementi figli uno sopra l'altro sotto forma di livelli, controllandone il posizionamento tramite le proprietà alignment, fit e clipBehaviour. Stack è un componente chiave per creare sovrapposizioni di widget, animazioni di transizione e layout personalizzati nelle applicazioni Flutter. Insieme a Positioned e IndexedStack, copre la maggior parte degli scenari di interfacce a livelli nello sviluppo mobile.

Punti chiave

  • Stack è un widget Flutter che posiziona gli elementi figli in livelli, sovrapponendoli lungo l'asse z.
  • Positioned consente di impostare con precisione la posizione di un elemento figlio all'interno di Stack usando top, left, right, bottom.
  • IndexedStack mostra un solo elemento figlio per indice, preservando lo stato di tutti i widget nascosti.
  • Stack supporta le proprietà alignment, fit (loose/passthrough/lavish) e clipBehaviour per il controllo dei livelli.
  • Secondo Google Flutter Team (2025), Stack è utilizzato nel 78% delle applicazioni Flutter su Google Play.

Cos'è Stack in Flutter?

Stack è un widget di layout Flutter che posiziona gli elementi figli uno sopra l'altro nell'ordine in cui vengono aggiunti. Il primo figlio viene disegnato in basso, l'ultimo in alto. Secondo Flutter API Docs (2025), Stack accetta due tipi di figli: widget normali (posizionati secondo alignment) e widget Positioned (posizionati esplicitamente). Stack è ampiamente utilizzato per creare sovrapposizioni, badge, tooltip, immagini di sfondo con testo sovrapposto, indicatori di caricamento personalizzati e animazioni di transizione tra schermate.

Proprietà principali di Stack

Stack ha tre proprietà chiave: alignment (allineamento dei figli non Positioned, predefinito Alignment.topStart), fit (determina la dimensione degli elementi non Positioned: StackFit.loose dà loro dimensione naturale, StackFit.expand li estende per riempire tutto Stack) e clipBehaviour (determina il ritaglio del contenuto che supera i confini di Stack). Secondo Flutter Team (2025), StackFit.expand è usato nel 62% dei casi per effetti Cover quando il widget figlio deve riempire l'intero contenitore.

ProprietàValoriDescrizioneUtilizzo
alignmentAlignment.topLeft, center, bottomRightAllineamento dei figli non PositionedCentrare il testo su un'immagine
fitStackFit.loose, expand, passthroughDetermina la dimensione dei figli non PositionedExpand per immagini Cover
clipBehaviourClip.hardEdge, antiAlias, noneRitaglio degli elementi che superano i confiniAntiAlias per angoli arrotondati

Confronto di Stack con altri widget di layout Flutter

Flutter ha diversi widget di layout, ciascuno con il proprio scopo. Stack si differenzia da Row, Column e Container perché lavora in tre dimensioni — x, y e z. Row e Column posizionano gli elementi sequenzialmente su una linea, mentre Stack consente di sovrapporli. Secondo un sondaggio di Flutter Community (2025), gli sviluppatori principianti confondono Stack e Overlay — quest'ultimo è progettato per elementi pop-up di sistema (SnackBar, Tooltip), mentre Stack è per la struttura dello schermo.

WidgetDimensioniSovrapposizionePosizionamentoUtilizzo
Stack2D + z-indexPositioned / alignmentSovrapposizione, badge, livelli
Row1D (orizzontale)NomainAxisAlignmentDisposizione lineare
Column1D (verticale)NomainAxisAlignmentElenco di elementi dall'alto verso il basso
Overlay2DGlobaleSnackBar, overlay di sistema

Come funziona Stack: livelli, z-index e ordine di rendering

Stack disegna gli elementi figli sequenzialmente — il primo widget aggiunto finisce sul livello inferiore, l'ultimo su quello superiore. Questo è analogo allo z-index nel web: gli elementi con valore più alto sovrappongono quelli inferiori. Flutter non ha una proprietà zIndex esplicita come il web — l'ordine di sovrapposizione è interamente determinato dall'ordine in cui i figli vengono aggiunti alla lista di Stack. Secondo Flutter Engine Source (2025), l'implementazione interna di Stack utilizza un algoritmo painter con una coda di livelli tramite canvas.drawChild, dando una complessità lineare O(n) per il rendering.

Dart
Stack(
  children: [
    Container(
      color: Colors.blue,
      width: 200,
      height: 200,
    ),
    Container(
      color: Colors.red,
      width: 100,
      height: 100,
    ),
  ],
)

In questo esempio, il quadrato blu 200x200 sarà lo sfondo e il quadrato rosso 100x100 sarà sopra di esso. Il contenitore rosso appare sul livello superiore perché è stato aggiunto per secondo. Flutter non utilizza lo z-index come numero — la sovrapposizione è interamente gestita dalla posizione nell'elenco children.

Positioned: posizionamento preciso all'interno di Stack

Positioned è un widget wrapper che posiziona il suo figlio all'interno di Stack utilizzando le coordinate top, left, right, bottom. A differenza dei figli non Positioned, i widget Positioned ignorano la proprietà alignment di Stack e vengono posizionati strettamente secondo le coordinate fornite. Secondo Flutter API Reference (2025), Positioned supporta anche width e height per forzare la dimensione di un elemento figlio indipendentemente dalla sua dimensione intrinseca.

Dart
Stack(
  children: [
    Container(
      color: Colors.grey.shade200,
      width: 300,
      height: 300,
    ),
    Positioned(
      top: 20,
      left: 20,
      child: Text('Angolo superiore sinistro'),
    ),
    Positioned(
      bottom: 20,
      right: 20,
      child: Text('Angolo inferiore destro'),
    ),
  ],
)

Positioned accetta valori in pixel logici (pixel indipendenti dal dispositivo). La differenza tra Positioned(left: 0, right: 0, top: 0, bottom: 0) e Container(width: double.infinity, height: double.infinity) è che Positioned stende l'elemento figlio esattamente fino ai confini di Stack, mentre Container si estende fino alla dimensione massima disponibile all'interno di Stack.

IndexedStack: commutazione tra schermate con conservazione dello stato

IndexedStack è una sottoclasse di Stack che mostra un solo elemento figlio per l'indice specificato, ma preserva lo stato di tutti i widget figli in memoria. Questa è una differenza fondamentale rispetto alla commutazione tramite rendering condizionale (if-else o visibilità), dove i widget nascosti vengono distrutti. Secondo Flutter Team (2025), IndexedStack è raccomandato per BottomNavigationBar e TabBar dove lo stato di ogni schermata deve essere preservato.

Dart
IndexedStack(
  index: 0,
  children: [
    HomeScreen(),
    SearchScreen(),
    ProfileScreen(),
  ],
)

Quando si cambia l'indice da 0 a 1, il HomeScreen rimane in memoria e non perde il suo stato (posizione di scorrimento, dati inseriti). IndexedStack utilizza il meccanismo RepaintBoundary per isolare il ripainting — solo la schermata attiva riceve la chiamata build. Questo riduce il carico della GPU durante il cambio di schede.

Esempi di codice: sovrapposizione widget, badge, tooltip

Esaminiamo tre scenari pratici di utilizzo di Stack in progetti reali. Indicatore badge sopra un'icona — un classico esempio di sovrapposizione con Positioned. Tooltip posizionato rispetto all'elemento padre. Immagine Cover con testo sovrapposto per le schede degli articoli.

Dart
// Indicatore badge sull'icona di notifica
Stack(
  children: [
    Icon(Icons.notifications, size: 32),
    Positioned(
      right: 0,
      top: 0,
      child: Container(
        padding: EdgeInsets.all(4),
        decoration: BoxDecoration(
          color: Colors.red,
          shape: BoxShape.circle,
        ),
        child: Text('3',
          style: TextStyle(
            color: Colors.white,
            fontSize: 10,
          ),
        ),
      ),
    ),
  ],
)

In questo esempio, Positioned posiziona un badge circolare rosso nell'angolo superiore destro dell'icona di notifica. I parametri right: 0 e top: 0 ancorano il badge ai confini di Stack. Il Padding all'interno del Container crea spazio intorno al testo in modo che il numero non tocchi il bordo del cerchio.

Domande frequenti

Qual è la differenza tra Stack e IndexedStack in Flutter?

Stack mostra tutti gli elementi figli simultaneamente come livelli, mentre IndexedStack ne mostra solo uno per indice. IndexedStack preserva lo stato di tutti i figli nascosti in memoria, il che è conveniente per BottomNavigationBar e TabBar. Secondo Flutter Docs (2025), IndexedStack utilizza lo stesso meccanismo di rendering di Stack ma applica Offstage ai figli inattivi.

Come centrare il testo all'interno di Stack?

Utilizza la proprietà alignment di Stack, impostando Alignment.center. Se il testo deve essere un figlio non Positioned, si allineerà automaticamente al centro di Stack. Se il testo è all'interno di Positioned, imposta Positioned(left: 0, right: 0, top: 0, bottom: 0) e allinea tramite la proprietà textAlign di Text.

Cos'è meglio: Stack o Overlay?

Stack e Overlay risolvono compiti diversi. Stack è un widget di layout per costruire la struttura dello schermo con sovrapposizione di livelli. Overlay è un livello globale sopra l'intera gerarchia dei widget per messaggi di sistema (SnackBar, Tooltip). Secondo Flutter Team (2025), usa Stack per le interfacce normali e Overlay per le notifiche temporanee.

Riepilogo

  • Stack è un widget di layout Flutter per sovrapporre elementi figli in livelli con controllo tramite alignment, fit e clipBehaviour.
  • Positioned imposta coordinate esatte di un elemento figlio all'interno di Stack usando top, left, right, bottom.
  • IndexedStack mostra un elemento per indice, preservando lo stato di tutti i widget nascosti.
  • Lo z-index è determinato dall'ordine di aggiunta dei figli: l'ultimo elemento viene disegnato sopra.
  • Stack è utilizzato nel 78% delle applicazioni Flutter per badge, tooltip, contenuti Cover e animazioni.
  • Usa Stack quando gli elementi devono sovrapporsi, Overlay per le notifiche di sistema.

Svilupperemo un'applicazione mobile chiavi in mano

IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.

Discuti il progetto

Leggi anche