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

Creazione di un Floating Action Button e Snack Bar

Floating Action Button (FAB) e Snackbar sono due widget immancabili all'interno di qualsiasi app mobile moderna: ecco come implementarli su Flutter.
Floating Action Button (FAB) e Snackbar sono due widget immancabili all'interno di qualsiasi app mobile moderna: ecco come implementarli su Flutter.
Link copiato negli appunti

Nello sviluppo di un'applicazione mobile moderna, non può mancare l'utilizzo dei Floating Action Button (FAB), ossia quei pulsanti circolari che permettono all'utente di eseguire un'azione primaria per quella schermata, e che generalmente troviamo in basso a destra nella schermata.

Alcuni esempi classici sono proprio l'inserimento di un nuovo elemento in una lista e l'invio di una nuova e-mail.

Insieme a questo componente, troviamo spesso anche l'utilizzo delle Snackbar, cioè un particolare widget introdotto dal Material Design, per dare un feedback all'utente sull'operazione compiuta o che verrà compiuta. La caratteristica tipica di questo componente è quella di comparire sullo schermo per un dato lasso di tempo e di non richiede un'interazione da parte dell'utente per chiuderlo.

In questa lezione, approfondiremo questi widget, analizzandone alcune personalizzazioni ed imparando a mostrare una Snackbar al tocco del FAB.

Le classi FloatingActionButton e SnackBar

Come di consueto, familiarizziamo con le principali proprietà di questi due widget prima di utilizzarli. Partiamo dal FloatingActionButton.

Proprietà Tipo Accettato Descrizione
backgroundColor Color imposta il colore di riempimento del bottone. Di default questo colore è impostato a ThemeData.accentColor
child Widget definisce l'elemento figlio del FAB e può essere un widget qualsiasi, come un'icona
elevation double rappresenta il livello di elevazione scelto per il FAB. Di default il valore è impostato a 6 e non può essere negativo
foregroundColor Color definisce il colore da usare per l'icona e il testo del FAB. Di default è impostata al valore ThemeData.accentIconTheme.color definito per il tema
mini bool controlla la dimensione del bottone e se impostata a true diminuisce la dimensione del FAB
onPressed VoidCallback definisce la callback da invocare quando l'utente clicca sul FAB
shape ShapeBorder permette di definire una forma personalizzata per il FAB, come già visto in precedenza per altri widget

Si tratta di proprietà semplici ma da tenere sempre ben a mente quando si lavora con i FloatingActionButton, in quanto indispensabili per modificarne il comportamento. Inoltre, questo widget offre il costruttore FloatingActionButton.extended per la creazione di un FAB avente la forma StadiumBorder (di cui abbiamo già parlato nella lezione 15), con la possibilità di aggiungere un'icona e del testo.

Vediamo, invece, adesso le principali proprietà della SnackBar fornita da Flutter.

Proprietà Tipo Accettato Descrizione
action SnackBarAction permette di definire un'azione che l'utente può compiere in base al messaggio scritto. Ad esempio, annullare l'operazione appena compiuta
backgroundColor Color se specificata, definisce il colore della SnackBar. Di default il colore è impostato a ThemeData.snackBarTheme.backgroundColor
behavior SnackBarBehavior definisce il comportamento e la posizione della SnackBar
content Widget rappresenta il contenuto della SnackBar che può essere ad esempio un semplice testo o un Widget più elaborato
duration Duration definisce per quanto tempo deve essere mostrata la SnackBar. Di default è a 4 sec
elevation double rappresenta il livello di elevazione scelto per la SnackBar. Di default il valore è impostato a 6 e non può essere negativo
shape ShapeBorder permette di definire una forma personalizzata per la SnackBar

Queste proprietà sono tutto quello che ci occorre per utilizzare al meglio le SnackBar.

Per ulteriori informazioni su questi widget e sulle altre proprietà fornite, si rimanda alla documentazione ufficiale e alle linee guida del Material Design.

Esempi pratici

Entriamo nel vivo della lezione con alcuni esempi utili per gestire e personalizzare i widget FloatingActionButton e SnackBar.

Per iniziare, creiamo un nuovo progetto come mostrato nella lezione 6 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 la proprietà floatingActionButton che andremo a impostare di volta in volta con la definizione di un nuovo esempio di FloatingActionButton.

class MyFAB extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text('Lesson 21'),
        ),
        body: Container(
          child: Center(
            child: Text("Default Scaffold Body"),
          ),
        ),
        floatingActionButton: /*Set FAB here*/);
  }
}

Come si può facilmente intuire, un FloatingActionButton può essere definito solo tramite la proprietà floatingActionButton offerta dal widget Scaffold.

Partiamo da una semplice implementazione di FloatingActionButton composto da un'icona e al cui tocco si genererà una stampa nel terminale. Per farlo, impostiamo un widget Icon come figlio del FloatingActionButton e implementiamo la callback per la proprietà onPressed affinché, ogni volta che l'utente tocca il bottone, verrà stampato un messaggio in console. Di seguito l'implementazione.

Widget _myBasicFAB() {
    return FloatingActionButton(
      child: Icon(Icons.add),
      onPressed: () {
        print("FAB clicked");
      },
    );
  }

Impostando la proprietà floatingActionButton del nostro Scaffold con il metodo _myBasicFAB() appena creato ed eseguendo l'applicazione avremo il seguente risultato.

Figura 136. Esempio di FloatingActionButton per a) Android b) iOS

Esempio di FloatingActionButton per a) Android b) iOS

Un altro esempio di facile realizzazione riguarda l'utilizzo del costruttore FloatingActionButton.extended per la creazione di un FAB con la forma di uno StadiumBorder. Vediamo insieme come.

Widget _myFABextended() {
    return FloatingActionButton.extended(
      onPressed: () {},
      icon: Icon(Icons.email),
      label: Text("New e-mail"),
    );
  }

Grazie a questo costruttore, abbiamo potuto creare un nuovo FloatingActionButton che definisce un'icona della email e una label rappresentanti l'azione. Utilizzando questo metodo come valore della proprietà floatingActionButton, otterremo il risultato in figura.

Figura 137. Esempio di utilizzo del costruttore FloatingActionButton.extended per a) Android b) iOS

Esempio di utilizzo del costruttore FloatingActionButton.extended per a) Android b) iOS

Come si può notare, il FAB sarà composto dall'icona e dal testo dell'azione, che aiuterà l'utente a comprendere al meglio come utilizzare questo componente.

Abbiamo appreso nel corso di queste lezioni che la personalizzazione dei widget è un aspetto fondamentale nello sviluppo di un'app, in quanto l'applicazione deve essere uniforme e non presentare cambi di stile incoerenti. Pertanto, è possibile personalizzare anche il FloatingActionButton. Ad esempio possiamo modificarne i colori attraverso le proprietà backgroundColor e foregroundColor, come segue.

Widget _myFABcustomColor() {
    return FloatingActionButton(
      onPressed: () {},
      child: Icon(
        Icons.email,
      ),
      backgroundColor: Colors.amber,
      foregroundColor: Colors.deepOrange,
    );
  }

In questo caso eseguendo l'applicazione, una volta aggiornata di conseguenza la proprietà floatingActionButton, otterremo un FAB dove il background del bottone è color ambra e l'icona è arancione scuro, come mostrato di seguito.

Figura 138. Personalizzazione dei colori del FloatingActionButton per a) Android b) iOS

Personalizzazione dei colori del FloatingActionButton per a) Android b) iOS

Attenzione però, se modificassimo il colore dei singoli elementi all'interno del FAB, come ad esempio il colore dell'icona, questa andrà a sovrascrivere sempre il colore definito dalla proprietà foregroundColor. Ad esempio, definendo il colore dell'icona come segue

Widget _myFABColorVsFgColor() {
    return FloatingActionButton(
      onPressed: () {},
      child: Icon(
        Icons.email,
        color: Colors.purple,
      ),
      backgroundColor: Colors.amber,
      foregroundColor: Colors.deepOrange,
    );
  }

otterremo che il colore arancione scuro della proprietà foregroundColor venga sovrascritto dal colore viola definito in Icon.

Figura 139. Esempio di sovrascrittura del colore foregroundColor per a) Android b) iOS

Esempio di sovrascrittura del colore foregroundColor per a) Android b) iOS

Un'altra personalizzazione utile è data dalla proprietà mini, che permette di creare un FloatingActionButton di dimensioni contenute. Ad esempio, impostando a true questa proprietà come nell'esempio seguente

Widget _myFABmini() {
    return FloatingActionButton(
      onPressed: () {},
      child: Icon(Icons.email),
      mini: true,
    );
  }

otterremo il risultato in figura.

Figura 140. Utilizzo della proprietà mini per a) Android b) iOS

Utilizzo della proprietà mini per a) Android b) iOS

Se invece non è la dimensione ciò che ci interessa modificare del FAB, bensì la sua forma, allora dobbiamo utilizzare la proprietà shape definendo la forma che più ci interessa.

Ad esempio, immaginiamo di voler creare un FloatingActionButton rettangolare con un bordo color ambra, allora dovremo definire la proprietà shape tramite il widget RoundedRectangleBorder, come segue.

Widget _myFABcustomShape() {
    return FloatingActionButton(
      onPressed: () {},
      child: Icon(Icons.email),
      shape: RoundedRectangleBorder(
          side: BorderSide(color: Colors.amber, width: 5.0)),
    );
  }

Eseguendo l'applicazione, otterremo quanto mostrato in figura.

Figura 141. Personalizzazione della forma di un FloatingActionButton per a) Android b) iOS

Personalizzazione della forma di un FloatingActionButton per a) Android b) iOS

Essendo un componente che va a sovrapporsi sul resto degli elementi della schermata è fondamentale che il FAB risulti rialzato rispetto agli elementi sottostanti come un listato. Per farlo, basta definire il valore più corretto per noi per la proprietà elevation. Ad esempio:

Widget _myFABelevation() {
    return FloatingActionButton(
      onPressed: () {},
      child: Icon(Icons.email),
      elevation: 10,
    );
  }

in questo caso abbiamo impostato a 10 la proprietà elevation che, grazie all'ombra generata, farà risultare più in alto il FAB rispetto agli altri componenti, come si può notare dalla figura seguente.

Figura 142. Utilizzo della proprietà elevation per a) Android b) iOS

Utilizzo della proprietà elevation per a) Android b) iOS

Infine, uno degli aspetti più importanti è proprio la posizione del FAB nella schermata con cui l'utente andrà ad interagire. A questo proposito, possiamo utilizzare la proprietà floatingActionButtonLocation di Scaffold, che accetta una delle proprietà definite per il widget FloatingActionButtonLocation che forniscono una posizione precisa del FloatingActionButton all'interno dello Scaffold. Vediamo alcuni semplici esempi.

Per posizionare in basso al centro un FAB, basterà impostare la proprietà FloatingActionButtonLocation.centerFloat come segue.

floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,

ottenendo quanto mostrato in figura.

Figura 143. Posizionamento del FAB al centro in basso nello Scaffold per a) Android b) iOS

Posizionamento del FAB al centro in basso nello Scaffold per a) Android b) iOS

Se invece volessimo posizionarlo in alto a destra dello Scaffold, basterà impostare il valore FloatingActionButtonLocation.endTop come segue:

floatingActionButtonLocation: FloatingActionButtonLocation.endTop,

ottenendo il risultato desiderato.

Figura 144. Posizionamento del FAB in alto a destra nello Scaffold per a) Android b) iOS

Posizionamento del FAB in alto a destra nello Scaffold per a) Android b) iOS

Queste ovviamente non sono le uniche posizioni possibili, ve ne sono altre che possono essere di aiuto nella realizzazione della vostra applicazione e sono consultabili tramite la documentazione ufficiale.

Ora che abbiamo compreso come definire un FloatingActionButton, vediamo come possiamo definire e mostrare una SnackBar quando il FAB viene toccato dall'utente.

Questa volta definiamo una nuova classe MyScaffoldFABwithSnackBar che estende la classe StatelessWidget e ha come scopo quello di creare un nuovo FloatingActionButton, la cui proprietà onPressed specifica una callback che:

  • definisce una SnackBar;
  • associa la SnackBar allo Scaffold.

Partiamo dalla definizione della SnackBar e immaginiamo di voler creare una SnackBar con le seguenti caratteristiche:

  • il content sarà un semplice testo;
  • l'action definirà una SnackBarAction che definirà la scritta CLOSE di colore bianco che, se premuta dall'utente, mostrerà un messaggio in console;
  • la forma della SnackBar avrà i bordi arrotondati e un contorno ambra;
  • il colore di background sarà viola;
  • la SnackBar verrà mostrata per 2 secondi.

Per farlo definiamo quindi una variabile mySnackBar di tipo SnackBar come segue.

SnackBar mySnackBar = SnackBar(
      content: Text('Hello!'),
      action: SnackBarAction(
          label: "CLOSE",
          textColor: Colors.white,
          onPressed: () {
            debugPrint('clicking on CLOSE');
          }),
      shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.all(Radius.circular(5)),
          side: BorderSide(color: Colors.amber, width: 5.0)),
      backgroundColor: Colors.purple,
      duration: Duration(milliseconds: 2000),
    );

In questo modo abbiamo definito la nostra SnackBar, che può finalmente essere associata allo Scaffold utilizzando la seguente riga di codice:

Scaffold.of(context).showSnackBar(mySnackBar)

Grazie a essa, siamo in grado di trovare lo Scaffold di interesse nel widget tree e lo utilizziamo per mostrare la SnackBar tramite il metodo showSnackBar.

Mettendo quindi insieme i pezzi, definiamo la classe MyScaffoldFABwithSnackBar come segue.

class MyScaffoldFABwithSnackBar extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return FloatingActionButton(
      onPressed: () {
        SnackBar mySnackBar = SnackBar(
    // . . .
        );
        Scaffold.of(context).showSnackBar(mySnackBar);
      },
      child: Icon(Icons.notifications),
    );
  }
}

Definita la classe, non ci resta che modificare la classe MyApp per permettere la visualizzazione della SnackBar. Modifichiamo poi la proprietà home affinché definisca uno Scaffold con un floatingActionButton.

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

Eseguendo l'applicazione otterremo il seguente risultato.

Figura 145a. Esempio di utilizzo si una SnackBar con FloatingActionButton per Android

Esempio di utilizzo si una SnackBar con FloatingActionButton per Android

Figura 145b. Esempio di utilizzo si una SnackBar con FloatingActionButton per iOS

Esempio di utilizzo si una SnackBar con FloatingActionButton per iOS

Come possiamo vedere dall'animazione, quando l'utente clicca sul FAB viene:

  • mostrata la SnackBar;
  • il FAB viene spostato in alto nella schermata per essere sempre disponibile all'utente senza essere coperto dalla notifica.

Qualora volessimo mostrare la SnackBar in un punto diverso dalla posizione di default, possiamo utilizzare le proprietà behavior ed elevation del widget.

Ad esempio, possiamo definire le proprietà come segue:

behavior: SnackBarBehavior.floating,
  elevation: 8,

In questo modo abbiamo dato un'elevazione di 8 e stabilito che SnackBar debba essere mostrata al di sopra di altri widget.

Aggiungiamo le due proprietà alla SnackBar definita in precedenza ed eseguiamo l'app, ottenendo i risultati in figura.

Figura 146a. Esempio di utilizzo della proprietà behavior per Android

Esempio di utilizzo della proprietà behavior per Android

Figura 146b. Esempio di utilizzo della proprietà behavior per iOS

Esempio di utilizzo della proprietà behavior per iOS

Il codice di questa lezione è disponibile su GitHub.

Ti consigliamo anche