Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial
  • Lezione 17 di 37
  • livello intermedio
Indice lezioni

Stack Widget per la sovrapposizione di widget

Impariamo a creare layout con widget sovrapposti, tramite l'uso dello Stack widget fornito da Flutter, framework per creare app mobile multipiattaforma.
Impariamo a creare layout con widget sovrapposti, tramite l'uso dello Stack widget fornito da Flutter, framework per creare app mobile multipiattaforma.
Link copiato negli appunti

Nella precedente lezione, abbiamo mosso i primi passi nella definizione di multi-child layout attraverso l’uso di Row e Column. Questi però non sono gli unici widget definiti da Flutter per creare interfacce complesse. Tra essi, infatti, c’è lo Stack Widget che permette la sovrapposizione di più widget su layer differenti.

In questa lezione ci focalizzeremo proprio su questo componente attraverso alcuni esempi pratici, per meglio cogliere gli aspetti fondamentali e gli utilizzi di questo widget.

Stack Widget

Analogamente a quanto visto finora, lo Stack widget può contenere molteplici widget figli che si trovano, a differenza dei widget Row e Column, su livelli differenti, componendo una vera e propria pila di elementi. Questo componente è quindi molto utile quando vogliamo sovrapporre diversi widget per creare interfacce nuove e articolate.

In uno Stack widget:

  • il primo widget nella lista dei widget figli è quello di base;
  • i widget figli successivi al primo sono sovrapposti al primo e tra loro, posizionandosi su layer differenti;
  • non è possibile effettuare lo scroll dei widget figli;
  • è possibile ritagliare i nodi figli che superano il box di rendering definito evitando effetti visivi poco gradevoli.

Uno degli aspetti particolari di questo questo widget è la possibilità di collocare i widget figli in una specifica posizione in base alla definizione o meno del widget Positioned Stack Positioned

Proprietà Tipo Accettato Descrizione
bottom double rappresenta la distanza tra il bordo inferiore del nodo figlio e la parte inferiore dello Stack
child Widget il widget da inserire nello Stack
height double l’altezza del nodo figlio
left double rappresenta la distanza tra il bordo sinistro del nodo figlio e il lato sinistro dello Stack
right double rappresenta la distanza tra il il bordo destro del nodo figlio e il lato destro dello Stack
top double rappresenta la distanza tra il bordo superiore del nodo figlio e la parte superiore dello Stack
width double la larghezza del nodo figlio

Attraverso queste proprietà è facile definire la posizione dei widget che devono essere messi nella pila. Tutti i widget racchiusi in un Positioned Stack positioned child

È bene precisare che non è obbligatorio usare il Positioned Stack alignment non-positioned child

Infine, indipendentemente dalla posizione dei widget, la dimensione dello Stack

Le proprietà

Come tutti i widget che abbiamo visto in queste lezioni, lo Stack widget fornisce poche ma utili proprietà per organizzare la pila di widget da mostrare. Tra queste abbiamo:

Proprietà Tipo Accettato Descrizione
alignment AlignmentGeometry come allineare i non-positioned child
children List<Widget> racchiude la lista di componenti da visualizzare nella pila
fit StackFit come devono essere dimensionati nella pila i non-positioned child. Ciò è reso possibile dall’utilizzo delle proprietà del widget StackFit
overflow Overflow utilizza le proprietà del widget Overflow Stack Overflow.clip Stack
textDirection TextDirection la direzione del testo

Vediamo adesso qualche esempio pratico di utilizzo per poter sfruttare al meglio gli Stack

Esempi pratici

Per iniziare, creiamo un nuovo progetto come mostrato in una precedente lezione di questa guida e, lasciando inalterati gli import, il metodo main() e la classe MyApp, cancelliamo il resto per aggiungere il seguente StatelessWidget, composto da uno Scaffold per la definizione dell’AppBar e di una SingleChildScrollView (di cui abbiamo già parlato nella lezione 11) che conterrà tutti i nostri esempi pratici di import delle immagini.

class MyPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Lesson 16'),
      ),
      body: SingleChildScrollView(
          child: Column(
            children: <Widget>[
              //we will add our widgets here.
            ],
          )),
    );
  }
}

Modifichiamo infine la classe MyApp per impostare il widget appena creato come home.

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      // . . .
      home: MyPage(),
    );
  }
}

Ora siamo pronti per le nostre sperimentazioni.

Vediamo da subito un semplice esempio di utilizzo immaginando di voler creare un Stack composto da tre diversi Container di diverse dimensioni e senza una specifica posizione. Inseriamo inoltre lo Stack all’interno di un altro Container.

Container(
      margin: EdgeInsets.only(top: 10),
      child: Stack(
        children: <Widget>[
          // Max Size
          Container(
            color: Colors.orange,
            height: 300,
            width: 300,
          ),
          Container(
            color: Colors.yellowAccent,
            height: 200.0,
            width: 200.0,
          ),
          Container(
            color: Colors.greenAccent,
            height: 100.0,
            width: 100.0,
          )
        ],
      )),

Eseguendo l’app, possiamo notare che tutti e tre gli elementi sono posizionati nell’angolo in alto a sinistra della schermata e, grazie alla differenza di dimensioni, è possibile vedere i diversi Container

Figura 107. Creazione di un semplice Stack widget composto da tre Container per a) Android e b) iOS (click per ingrandire) Creazione di un semplice Stack widget composto da tre Container per a) Android e b) iOS

Per ovviare a questo problema possiamo sfruttare la proprietà alignment Stack

Container(
    margin: EdgeInsets.only(top: 10),
    child: Stack(
      alignment: Alignment.centerRight,
      children: <Widget>[
        Container(
          color: Colors.orange,
          height: 300,
          width: 300,
        ),
        Container(
          color: Colors.yellowAccent,
          height: 200.0,
          width: 200.0,
        ),
        Container(
          color: Colors.greenAccent,
          height: 100.0,
          width: 100.0,
        )
      ],
    ),
  ),

Eseguendo l’app, possiamo vedere che impostando la proprietà a Alignment.centerRight Stack Container

Figura 108. Utilizzo della proprietà alignment impostata a Alignment.centerRight per a) Android e b) iOS (click per ingrandire) Utilizzo della proprietà alignment impostata a Alignment.centerRight per a) Android e b) iOS

Una volta visto come disporre lo Stack Stack Stack

  • utilizzare il widget Align
  • utilizzare il widget Positioned

Vediamo come utilizzare entrambe le opzioni.

Prendiamo in considerazione il primo esempio mostrato in questa lezione e modifichiamo le dimensioni dei widget. Prendiamo l’ultimo Container dello Stack e incapsuliamolo all’interno dell’Align widget. Impostiamo inoltre la proprietà alignment a Alignment.topRight per posizionare il nostro elemento in alto a destra nello Stack.

Align(
  alignment: Alignment.topRight,
  child: Container(
    color: Colors.greenAccent,
    height: 100.0,
    width: 100.0,
  )
)

Il risultato di questa modifica è visibile nella seguente immagine.

Figura 109. Utilizzo dell’Align widget per il posizionamento di un elemento nello Stack per a) Android e b) iOS (click per ingrandire) Utilizzo dell’Align widget per il posizionamento di un elemento nello Stack per a) Android e b) iOS

Nonostante l'uso di Align Container Positioned

Analogamente a quanto fatto prima, incapsuliamo l’ultimo widget all’interno del widget Positioned right top Container

Positioned(
    right: 50.0,
    top: 60.0,
    child: Container(
      color: Colors.greenAccent,
      height: 100.0,
      width: 100.0,
    )
  )

Questa modifica ci permette di avere il risultato mostrato nella seguente figura e un maggiore controllo sul posizionamento dell’elemento nello Stack

Figura 110. Utilizzo del Positioned widget per il posizionamento di un elemento nello Stack (click per ingrandire) Utilizzo del Positioned widget per il posizionamento di un elemento nello Stack

Vediamo invece adesso come utilizzare la proprietà fit Stack fit Stack

Widget _setFitStack(fit) => Stack(
    fit: fit,
    children: [
      Container(
        color: Colors.greenAccent,
        height: 100.0,
        width: 100.0,
      )
    ],
  );

Usiamo quindi questa funzione con i tre possibili valori che abbiamo a disposizione per la proprietà fit

Valore Descrizione
loose rende i widget figli più piccoli possibile all’interno dello Stack
expand imposta la dimensione dei widget figli alla più grande possibile
passthrough il comportamento dipende dal nodo padre in cui è definito lo Stack

Invochiamo quindi la funzione all’interno del nostro codice come segue.

Container(
    constraints: BoxConstraints.expand(height: 160),
    child: _setFitStack(StackFit.loose),
  ),
  Container(
    constraints: BoxConstraints.expand(height: 160),
    child: _setFitStack(StackFit.expand),
  ),
  Container(
    color: Colors.black,
    alignment: Alignment.center,
    child: _setFitStack(StackFit.passthrough),
  ),

Come si può osservare, il metodo privato che abbiamo definito viene invocato all’interno di un apposito Container widget di cui vengono impostati dei vincoli di altezza per i primi due widget, mentre per il terzo Container sono state impostate alcune proprietà. Eseguendo quindi l’app, otterremo il seguente risultato.

Figura 111. Esempio di utilizzo della proprietà fit per a) Android e b) iOS (click per ingrandire) Figura 111. Esempio di utilizzo della proprietà fit per a) Android e b) iOS

È interessante notare come nel caso del valore loose Container passthrough Container

Vediamo infine la proprietà overflow Stack

Definiamo quindi una semplice funzione che, data la proprietà overflow Container Stack Text overflow

Widget _setOverflowStack(overflow) => Container(
    margin: EdgeInsets.only(top: 10),
    color: Colors.yellow[800],
    constraints: BoxConstraints.expand(height: 38),
    child: Stack(
      overflow: overflow,
      children: <Widget>[
        Positioned(
          top: 10,
          child: Text(
            "cogito ergo sum, cogito ergo sum, cogito ergo sum, cogito ergo sum,\ncogito ergo sum, cogito ergo sum",
            style: TextStyle(color: Colors.black, fontSize: 15),
          ),
        )
      ],
    ),
  );

Invochiamo quindi il metodo appena scritto passando come parametro il valore Overflow.visible Overflow.clip

Figura 112. Esempio di utilizzo della proprietà overflow per a) Android e b) iOS (click per ingrandire) Esempio di utilizzo della proprietà overflow per a) Android e b) iOS

Come si può notare, nel primo caso il testo fuoriesce dallo Stack Container

Compreso come usare le diverse proprietà, vediamo come creare uno Stack

Per fare ciò, dovremo creare uno Stack

  • un CircleAvatar
  • un Container Text

Creiamo quindi un semplice metodo generico che, dato in ingresso il percorso dell’immagine e il nome dell’utente, restituirà uno Stack widget come quello poc’anzi descritto.

Widget _buildStack(pic, name) => Stack(
    alignment: const Alignment(0.6, 0.6),
    children: [
      CircleAvatar(
        backgroundImage: AssetImage(pic),
        radius: 100,
      ),
      Container(
        decoration: BoxDecoration(
          color: Colors.black45,
        ),
        child: Text(
          name,
          style: TextStyle(
            fontSize: 20,
            fontWeight: FontWeight.bold,
            color: Colors.white,
          ),
        ),
      ),
    ],
  );

In questo caso, andiamo a invocare il metodo appena creato passando come nome da mostrare e immagine quelli che abbiamo a disposizione nella cartella assets specificata nel pubspec.yaml (vedi lezione 12 per maggiori dettagli). Inoltre, per motivi grafici centriamo il widget come segue.

Center(
    child: _buildStack('girl.jpg', 'Shawna'),
  )

Eseguendo l’app otterremo il seguente risultato.

Figura 113. Utilizzo di uno Stack widget per la visualizzazione di un’immagine e di un nome utente (click per ingrandire) Utilizzo di uno Stack widget per la visualizzazione di un’immagine e di un nome utente

Il codice di questa lezione è disponibile su GitHub

Ti consigliamo anche