Da Stateless a Stateful

Nel post precedente abbiamo visto come un'applicazione Flutter, per quanto complessa, si basa sostanzialmente su due tipi di widget: i widget Stateless e i widget Stateful. Nelle righe seguenti, partendo da un widget Stateless con un semplice layout, aggiungeremo quanto necessario per gestire uno stato e quindi un aggiornamento dell'aspetto.



Apriamo una finestra di terminale e utilizzando il comando cd, posizioniamoci nella cartella radice in cui vogliamo creare il nostro progetto 


 cd c:\work\flutter


e diamo il comando di creazione flutter create, aggiungendo il nome che vogliamo attribuire alla cartella che conterrà il progetto:


 flutter create flutter_stateful


Iniziamo con uno Stateless

Attendiamo che siano creati tutti i file del progetto e al termine apriamo la cartella appena creata con Visual Studio Code e modifichiamo file main.dart presente nella cartella lib, sostituendo il contenuto con il seguente codice

 
import 'package:flutter/material.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        appBar: AppBar(
          title: const Text("Un esempio di stateful widget"),
        ),
        body: Padding(
          padding: const EdgeInsets.all(40.0),
          child: Container(
            decoration: const BoxDecoration(
                shape: BoxShape.circle, color: Colors.amber),
          ),
        ),
        floatingActionButton: const FloatingActionButton(
          onPressed: null,
          tooltip: 'premi qui',
          child: Icon(Icons.circle),
        ),
      ),
    );
  }
}


Con questo codice definiamo una MaterialApp estendendo un StatelessWidget. Nel corpo dell'app, disegniamo un cerchio che non tocca i bordi, grazie al widget Padding e inseriamo un  FloatingActionButton a cui per il momento non è associato alcun evento. Se avviamo il debug dell'applicazione, otterremo questo risultato.


Convertiamo in Stateful

Con tasto destro del mouse sul StatelessWidget, quindi Refactor, Convert to StatefulWidget possiamo sfruttare gli automatismi previsti dall'ambiente di sviluppo Flutter per ottenere il nuovo codice in versione Stateful


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

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',

......


come si può notare, è stata aggiunta la nuova classe _MyAppState  che inizializza lo stato del widget. Adesso aggiungiamo quanto serve per riuscire modificare il colore del cerchio alla pressione del pulsante, ovvero ad aggioranare lo stato dell'app.

Definiamo una funzione _swapColor() da associare al pulsante, che sostanzialmente si occuperà di alternare tra due colori ogni volta che sarà chiamata. Per notificare a Flutter la necessità  di aggiornare lo stato dell'app, è sufficiente incapsulare il codice nella funzione setState():

...
 
class _MyAppState extends State<MyApp> {
  Color _circleColor = Colors.amber;

  void _swapColor() {
    setState(() {
      if (_circleColor == Colors.amber) {
        _circleColor = Colors.blueGrey;
      } else {
        _circleColor = Colors.amber;
      }
    });
  }

......


Modifichiamo la definizione di Container per usare la variabile _circleColor


...
          child: Container(
            decoration:
                BoxDecoration(shape: BoxShape.circle,
                color: _circleColor,
),
          ),
...

ed infine, associamo la funzione _swapColor  al pulsante


...
        floatingActionButton: FloatingActionButton(
          onPressed: _swapColor,
          tooltip: 'premi qui',
          child: const Icon(Icons.circle),
        ),
...

Terminate le integrazioni al codice, se lanciamo il debug dell'app, ad ogni click sul pulsante, il cerchio cambierà colore.


Chiaramente questo è solo un semplice esempio di un widget Stateful, ma può essere facilmente adattato ad altri usi più complessi, che magari vedremo nei prossimi articoli, introducendo altri widget.

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

Commenti