Flutter: AlertDialog, SnackBar e BottomSheet

Nell'articolo di oggi vedremo tre diversi modi per visualizzare dei messaggi sullo schermo, utili quando si vuole comunicare qualcosa all'utente, senza interrompere il flusso delle pagine. 


Il progetto base 

Creiamo un nuovo progetto e sostituiamo il codice standard nel file main.dart con questo.


import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: Home(),
    );
  }
}

class Home extends StatelessWidget {
  const Home({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Flutter demo'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [

          // qui inseriremo i nostri pulsanti

          ],
        ),
      ),
    );

  // qui inseriremo i metodi e le funzioni aggiuntive

  }


Messaggio SnackBar

Con SnackBar, si indica un breve messaggio su sfondo nero che viene visualizzato per un tempo limitato nella parte inferiore dello schermo (in altri linguaggi è chiamato toast). Aggiungiamo un pulsante per generarne uno:


            ElevatedButton(
              onPressed: () => _showSnackBar(context),
              child: const Text('Show toast'),
            ),


e definiamo la funzione _showSnackBar in questo modo:


  void _showSnackBar(BuildContext context) {
    final scaffold = ScaffoldMessenger.of(context);
    scaffold.showSnackBar(
      SnackBar(
        content: const Text('Questo è un toast'),
        action:
            SnackBarAction(label: 'X', onPressed: scaffold.hideCurrentSnackBar),
      ),
    );
  }


Oltre al messaggio abbiam aggiunto anche un pulsante (SnackBarAction) che permette di chiudere anticipatamente il messaggio. Alla pressione del pulsante il risultato che si ottiene dovrebbe essere questo: 


Alert dialog

Aggiungiamo un nuovo pulsante adesso per visualizzare la classica finestra di dialogo :


            const SizedBox(height: 20),
            ElevatedButton(
              onPressed: () => _showAlertDialog(context),
              child: const Text('Show alert dialog'),
            ),


e definiamo la funzione _showAlertDialog in questo modo:


  void _showAlertDialog(BuildContext context) {
    showDialog(
        context: context,
        builder: (context) {
          return AlertDialog(
              title: const Text("AlertDialog"),
              content: const Text("Questo è un messaggio"),
              actions: [
                TextButton(
                    child: const Text('Close'),
                    onPressed: () => Navigator.of(context).pop())
              ]);
        });
  }



Anche in questo caso è presente un pulsante per chiudere la finestra di dialogo (la chiusura utilizza lo stesso meccanismo già visto di navigazione tra le pagina)


                    onPressed: () => Navigator.of(context).pop())


Lanciando la funzione dovreste ottenere un risultato simile (con stile material


Se si volesse generare una finestra di dialogo in stile cupertino, occorre aggiungere la riga di importazione della relativa libreria


import 'package:flutter/cupertino.dart';


e modificare il codice della funzione _showAlertDialog in questo modo


  void _showAlertDialog(BuildContext context) {
    showDialog(
        context: context,
        builder: (context) {
          return CupertinoAlertDialog(
              title: const Text("AlertDialog"),
              content: const Text("Questo è un messaggio"),
              actions: [
                CupertinoButton(
                    child: const Text('Close'),
                    onPressed: () => Navigator.of(context).pop())
              ]);
        });
  }


per ottenere questo risultato


oppure si potrebbe scrivere una funzione che visualizza la finestra di dialogo coerente con la piattaforma su cui sta girando il codice.


    final platform = Theme.of(context).platform;

    if (platform == TargetPlatform.iOS) {
      _buildCupertinoAlert(context);
    } else {
      _buildMaterialAlert(context);
    }


BottomSheet

Aggiungiamo un nuovo pulsante adesso per visualizzare il terzo tipo di messaggio. Per ora tralasciamo il fatto che, a differenza dei casi precedenti, è stato necessario includere la definizione del pulsante in un widget Builder (questa particolarità merita un articolo a parte):


            const SizedBox(height: 20),
            Builder(builder: (context) {
              return ElevatedButton(
                onPressed: () => _showBottomsheet(context),
                child: const Text('Show bottom sheet'),
              );
            }),


e definiamo la funzione _showBottomsheet in questo modo:

 
  void _showBottomsheet(BuildContext context) {
    final controller = showBottomSheet(
        context: context,
        builder: (context) {
          return SafeArea(
              child: Container(
            color: Colors.red[200],
            width: double.infinity,
            child: Padding(
                padding: const EdgeInsets.symmetric(vertical: 30.0),
                child: Column(mainAxisSize: MainAxisSize.min, children: [
                  Text('BottomSheet!',
                      style: Theme.of(context).textTheme.headline6),
                  const Text('Questo è un messaggio')
                ])),
          ));
        });

    Future.delayed(const Duration(seconds: 5)).then((_) {
      controller.close();
    });
  }


Con questo codice costruiamo una vera e propria card con dei contenuti, visualizzata nella SafeArea in modo da non coprire la barra dei comandi inferiori e con una chiusura automatica dopo 5 secondi, implementata grazie a queste righe:


    Future.delayed(const Duration(seconds: 5)).then((_) {
      controller.close();
    });


Alla pressione del pulsante, il risultato dovrebbe essere simile a questo



La nostra applicazione di esempio è completa.

Come per gli articoli precedenti potete trovare questo codice tra le mie repo GitHub: https://github.com/luigimicco/flutter_alert

Commenti