Nella lezione precedente abbiamo preso confidenza con le classi MaterialApp
e ThemeData
per la definizione di temi. In questa lezione ci focalizzeremo su alcuni esempi pratici per definire ed utilizzare i temi all’interno della nostra applicazione.
Esempi pratici
Ora che abbiamo familiarizzato con questi Widget
analizzandone le proprietà, passiamo alla pratica e iniziamo a personalizzare la nostra applicazione. Per farlo partiamo con la creazione di una nuova app come illustrato nella lezione 6 di questa guida e, a differenza delle altre lezioni, lasciamo il codice inalterato in quanto andremo a lavorare proprio sull’applicazione di esempio fornita da questo framework. Riportiamo di seguito la struttura della classe MyApp
.
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: /*add here yout theme*/,
home: MyHomePage(title: 'Lesson 23'),
);
}
Come possiamo notare all’interno del metodo build ritroviamo il widget MaterialApp che di base definisce:
- un titolo;
- un tema;
- il widget per la home della nostra applicazione.
Di nostro interesse, infatti, è proprio la proprietà theme
MyApp
Partiamo da un semplice esempio che ci permette di impostare su dark
Per farlo, impostiamo la proprietà theme come segue.
theme: ThemeData.dark(),
ottenendo il seguente risultato una volta avviata l’applicazione.
Invocando semplicemente il metodo dark()
ThemeData
Vediamo quindi come possiamo definire un tema globale andando a creare un nuovo widget ThemeData
Immaginiamo di voler modificare nella nostra applicazione:
- la famiglia di font per usarne uno specifico;
- il colore primario e secondario;
- un tema personalizzato per i testi dell’applicazione.
Per farlo creiamo un nuovo metodo che si occuperà di creare e di restituire un nuovo ThemeData
ThemeData _myCustomThemeData() {
return ThemeData(
fontFamily: 'Roboto',
primaryColor: Colors.deepOrangeAccent,
accentColor: Colors.purple,
textTheme: TextTheme(
headline: TextStyle(fontWeight: FontWeight.w500, color: Colors.blue),
title: TextStyle(fontSize: 50),
caption: TextStyle(
fontWeight: FontWeight.w400, fontSize: 14.0, color: Colors.green),
body1: TextStyle(fontSize: 20, color: Colors.purple),
));
}
In particolare, del metodo appena definito è interessate notare il textTheme
TextTheme
headline
title
body1
caption
Per ogni proprietà usata di TextThema
TextStyle
lezione 14
Infine, come fontFamily
Roboto
Impostiamo quindi il metodo appena creato come valore della proprietà theme ed eseguiamo l’applicazione.
Il risultato è decisamente interessante in quanto, con poche righe di codice, siamo riusciti a modificare i colori dei widget e la dimensione dei testi senza intervenire esplicitamente su questi.
Se per questo tema volessimo modificare la proprietà primarySwatch
ThemeData _myCustomThemeDataDark() {
return ThemeData(
// . . .
primarySwatch: Colors.amber,
brightness: Brightness.dark,
));
}

Immaginiamo invece di voler definire uno stile per tutti i bottoni della nostra applicazione ma, invece di farlo manualmente, utilizziamo il buttonTheme
ThemeData
ThemeData _themeOverridingdefault() {
final ThemeData base = ThemeData.light();
return base.copyWith(
buttonTheme: base.buttonTheme.copyWith(
buttonColor: Colors.blueGrey,
shape: StadiumBorder(),
textTheme: ButtonTextTheme.primary,
splashColor: Colors.red,
)
);
}
A differenza del caso precedente, abbiamo creato un nuovo tema a partire dal tema light()
ThemeData
copyWith()
buttonTheme
buttonTheme
light
Questo approccio è molto utile nel momento in cui vogliamo modificare solo un aspetto di un tema definito in precedenza.
A questo punto, basterà aggiungere alla nostra schermata un RaisedButton
@override
Widget build(BuildContext context) {
return Scaffold(
// . . .
children: <Widget>[
// . . .
Divider(),
RaisedButton(
child: Text("my Button theme"),
onPressed: () {},
)
],
),
),
// . . .
}
Aggiorniamo quindi il tema della nostra applicazione per vedere il risultato delle modifiche effettuate.
Come possiamo vedere, sebbene non abbiamo modificato lo stile del RaisedButton
StadiumBorder
L’utilizzo dei temi globali è fondamentale quando vogliamo personalizzare col minimo sforzo i widget di base forniti dal framework, ma nel caso di custom widget creati da noi, il framework non sa quali colori associare o che stile tipografico applicare al testo.
Per poter applicare un particolare stile tipografico o un colore definito nel nostro tema a un nuovo widget, o a un qualsiasi altro widget di base della nostra applicazione, dobbiamo utilizzare il metodo Theme.of()
ThemeData
Ad esempio, utilizziamo il primo tema definito in questa lezione contenente la personalizzazione del textTheme
Theme.of()
@override
Widget build(BuildContext context) {
return Scaffold(
// . . .
children: <Widget>[
Container(
color: Theme.of(context).primaryColor,
child: Text('my custom theme',
style: Theme.of(context).textTheme.headline)),
Divider(),
Text(
'You have pushed the button this many times:',
style: Theme.of(context).textTheme.body1,
),
Text(
'$_counter',
style: Theme.of(context).textTheme.caption,
),
],
),
),
// . . .
}
In questo caso, per ogni componente testuale della nostra schermata abbiamo definito uno stile tra quelli presenti nel nostro textTheme
Eseguiamo quindi l’applicazione per vedere gli effetti della nostra modifica.
Il risultato ottenuto evidenzia come sia semplice riutilizzare i temi definiti per la nostra applicazione e quanto sia importante definire un tema per le nostre app al fine di:
- ridurre il codice ripetuto per lo stile di colori e testi;
- uniformare lo stile in tutte le sezioni dell’app.
Il codice di questa lezione è disponibile su GitHub