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

Usare ThemeData: esempi pratici

In questa lezione vedremo alcuni esempi pratici per imparare a definire ed utilizzare i temi nello sviluppo di un'app mobile multipiattaforma con Flutter.
In questa lezione vedremo alcuni esempi pratici per imparare a definire ed utilizzare i temi nello sviluppo di un'app mobile multipiattaforma con Flutter.
Link copiato negli appunti

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 per cui andremo a definire all’interno della classe MyApp diversi metodi per impostare un nuovo tema per la nostra applicazione.

Partiamo da un semplice esempio che ci permette di impostare su dark il tema della nostra applicazione usando i colori preimpostati.

Per farlo, impostiamo la proprietà theme come segue.

theme: ThemeData.dark(),

ottenendo il seguente risultato una volta avviata l’applicazione.

Figura 156. Tema dark per a) Android b) iOS (click per ingrandire)Tema dark per a) Android b) iOS

Invocando semplicemente il metodo dark() di ThemeData abbiamo cambiato completamente il tema della nostra applicazione da chiaro a scuro, ma siamo comunque legati a colori e stili preimpostati per noi.

Vediamo quindi come possiamo definire un tema globale andando a creare un nuovo widget ThemeData in cui specifichiamo noi stessi cosa vogliamo modificare del tema.

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, che ha come valore un nuovo widget di tipo TextTheme, il quale offre allo sviluppatore la possibilità di definire diversi stili tipografici, come ad esempio headline, title, body1, caption e molti altri ancora. Si raccomanda di consultare la documentazione relativa a questa classe per conoscere tutte le possibili proprietà e i valori raccomandati.

Per ogni proprietà usata di TextThema abbiamo definito uno specifico TextStyle (di cui abbiamo discusso nella lezione 14) definendo dimensione e colore.

Infine, come fontFamily abbiamo utilizzato Roboto a titolo d’esempio, in quanto è l’unica famiglia di font fornita da Flutter di default. Qualora volessimo usare un font diverso dovremmo importarlo come abbiamo già visto nella lezione 14.

Impostiamo quindi il metodo appena creato come valore della proprietà theme ed eseguiamo l’applicazione.

Figura 157. Definizione di un tema personalizzato per a) Android b) iOS (click per ingrandire)Definizione di un tema personalizzato per a) Android b) iOS

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à brightness e aggiungere la proprietà primarySwatch, basterà aggiungere al codice definito le seguenti definizioni.

ThemeData _myCustomThemeDataDark() {
    return ThemeData(
        // . . .
        primarySwatch: Colors.amber,
        brightness: Brightness.dark,
        ));
  }

Figura 158. Definizione di un tema personalizzato con brightness dark per a) Android b) iOS (click per ingrandire)Definizione di un tema personalizzato con brightness dark per a) Android b) iOS

Immaginiamo invece di voler definire uno stile per tutti i bottoni della nostra applicazione ma, invece di farlo manualmente, utilizziamo il buttonTheme offerto da ThemeData. Vediamo un esempio.

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() fornito da ThemeData e abbiamo sovrascritto tramite il metodo copyWith() la proprietà buttonTheme, che a sua volta è una copia del buttonTheme definito dal tema light e di cui abbiamo modificato alcuni aspetti.

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 per poter vedere gli effetti della nostra modifica. Riportiamo di seguito solo la porzione di codice nuova da integrare nel codice pre-esistente.

@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.

Figura 159a. Definizione di un tema per i bottoni per Android (click per ingrandire)Definizione di un tema per i bottoni per Android
Figura 159b. Definizione di un tema per i bottoni per iOS (click per ingrandire)Definizione di un tema per i bottoni per iOS

Come possiamo vedere, sebbene non abbiamo modificato lo stile del RaisedButton, quest’ultimo ha una forma ovoidale determinata dallo StadiumBorder e al tocco del bottone diventerà rosso. Tutto ciò grazie alla definizione del tema, che semplifica l’utilizzo dei widget di default forniti dal framework.

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() che, dato il contesto corrente, permette di accedere a tutte le proprietà di ThemeData.

Ad esempio, utilizziamo il primo tema definito in questa lezione contenente la personalizzazione del textTheme e modifichiamo tutti i componenti testuali della nostra applicazione mediante l’utilizzo del metodo Theme.of() come nel seguente esempio.

@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.

Figura 160. Utilizzo del metodo Theme.of() per a) Android b) iOS (click per ingrandire)Utilizzo del metodo Theme.of() per a) Android b) iOS

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.

Ti consigliamo anche