In questo articolo vedremo qual è la differenza tra uno StatelessWidget ed uno StatefulWidget e vedremo quando si usa uno piuttosto che l’altro.
I widgets in Flutter
In Flutter i Widgets sono utilizzati per creare un’interfaccia moderna in pochi minuti. I widgets sono il componente fondamentale di ogni applicazione sviluppata in Flutter.
I Widgets descrivono come la loro vista deve essere in base alla loro configurazione e allo stato in cui si trovano.
Ogniqualvolta lo stato di un widget cambia si ricrea la propria vista in base al nuovo stato in cui si trova.
A differenza di altri framework, all’interno di un’App sviluppata in Flutter ogni volta che uno stato cambia non viene ridisegnata tutta l’interfaccia, ma solo il Widget a cui appartiene lo stato.
La lista completa di tutti i Widget la potete trovare a questo link https://flutter.dev/docs/development/ui/widgets
Le due categorie di Widgets
In Flutter un widget può essere Stateless o Stateful. Vediamo la differenza tra i due:
Stateless Widget
Come ci fa intuire la parola “Stateless”, questo widget non ha uno stato e quindi non può cambiare.
Esempi di StatelessWidget sono Text, Icon e IconButton.
import 'package:flutter/material.dart';
//la prima funzione che viene eseguita quando viene avviata l'App
void main() {
runApp(MyApp());
}
//definiamo lo StatelessWidget
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'La mia bellissima App',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: AppBar(
title: Text("La mia bellissima App"),
),
body: Center(child:Text('Ecco la mia bellissima App!'))
),
);
}
}
Come si vede dal codice, abbiamo sviluppato una semplice App con un testo statico centrato nello schermo che non cambia mai.
Stateful Widget
A differenza del precedente, uno Stateful Widget è dinamico: cambia il suo aspetto ogni volta che l’utente genera un evento dovuto ad un’interazione con l’interfaccia o quando riceve dei dati.
Esempi di StatefulWidget sono Checkbox, Radio, Slider, Form e TextField.
Nel seguente codice vediamo come creare uno StatefulWidget per far incrementare un valore premendo un FloatingActionButton:
import 'package:flutter/material.dart';
//la prima funzione che viene eseguita quando viene avviata l'App
void main() {
runApp(MyHomePage());
}
//definiamo lo StateFulWidget
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
//definiamo lo Stato del Widget
class _MyHomePageState extends State {
int _counter = 0;
//la funzione che viene chiamate per cambiate lo stato
void _incrementCounter() {
//con setState() comunichiamo al widget che uno stato è cambiato e aumentiamo il contatore
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'La mia bellissima App',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: AppBar(
title: Text("La mia bellissima App"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Hai premuto il pulsante:',),
Text('$_counter', style: Theme.of(context).textTheme.headline4,),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Incrementa',
child: Icon(Icons.add),
),
),);
}
}
Come si vede dal codice, per fare in modo che venga cambiato lo stato del Widget, e quindi ridisegnata la sua interfaccia, bisogna chiamare la funzione setState(), dove al suo interno si possono cambiare i valori alle variabili degli oggetti presenti nel Widget.
Vediamo un esempio pratico: App per un quiz
Per capire meglio quello che abbiamo visto precedentemente, vediamo un esempio pratico: un’App per un quiz.
In questo caso avremo x domande a cui per ognuna bisogna registrare una risposta e una volta risposto andare avanti con le altre domande nel quiz, oppure mostrare il risultato finale.
Quale dei due widget bisogna utilizzare?
In questo caso si deve utilizzare uno StatefulWidget: ogni volta che l’utente risponde ad una domanda, bisogna chiamare la funzione setState() e registrare la risposta, calcolare l’eventuale punteggio e incrementare il contatore per andare alla domanda successiva.