Flutter : ajouter un thème à votre application
Flutter flutter, here we go again... ♪
Vous l'aurez deviné, nous allons encore une fois parler de Flutter dans ce nouvel article. Mais avant cela, un petit résumé pour ceux qui n'aurait pas tout suivi. Jusqu'ici, nous avons :
Aujourd'hui, nous allons donc reprendre cette dernière application et tenter de la rendre un peu plus jolie (je dis bien "tenter", je ne suis que dev).
Que je thème, que je thèèème ♫
La dernière fois, en détaillant le contenu de la classe App
, nous avons remarqué qu'un paramètre theme
était disponible dans le constructeur de MaterialApp
:
class MyApp extends StatelessWidget { // This widget is the root of your application. @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo Login', theme: ThemeData( primarySwatch: Colors.blue, ), home: MyHomePage(title: 'Connexion'), ); } }
C'est ce paramètre que nous allons modifier pour personnaliser notre petite application.
L'app aux yeux menthe à l'eau ♬
Commençons par choisir les couleurs de notre application.
Nous sommes dans une application de type Material
, cela implique donc de définir au moins deux couleurs : PrimaryColor
et SecondaryColor
. La couleur primaire sera celle de votre barre de navigation. La couleur secondaire sera la couleur d'accent, par exemple, la couleur de votre bouton flottant (FloatingActionButton
). Une fois ces deux couleurs choisies, il nous faut une déclinaison light et dark de ces couleurs. Vous pouvez les définir vous même, ou bien utiliser cet outil qui les génèrera pour vous. Pour ma part j'ai choisi la couleur #008080
en tant que couleur primaire et #b2dfdb
en secondaire (on dirait pas un peu des couleurs menthe à l'eau ?).
Ensuite, créons une classe qui contiendra le thème de notre application dans laquelle nous définirons nos couleurs. Les couleurs sont définies à l'aide de la classe Color
qui accepte les couleurs de la forme hexadécimale (avec les 8 digits). Ainsi ma couleur #008080
devient Color(0xFF008080)
.
import 'package:flutter/material.dart'; const PrimaryColor = const Color(0xFF008080); const PrimaryColorLight = const Color(0xFF4cb0af); const PrimaryColorDark = const Color(0xFF005354); const SecondaryColor = const Color(0xFFb2dfdb); const SecondaryColorLight = const Color(0xFFe5ffff); const SecondaryColorDark = const Color(0xFF82ada9); const Background = const Color(0xFFfffdf7); const TextColor = const Color(0xFF004d40); class MyTheme { }
Ah qu'elles sont jolies les couleurs de mon appli ♪
Maintenant que vous avons nos jolies couleurs, passons à la définition du thème. Ajoutons donc une propriété defaultTheme
qui appelle la méthode de construction du thème :
class MyTheme { static final ThemeData defaultTheme = _buildMyTheme(); static ThemeData _buildTheme() { } }
Dans la méthode _buildTheme
, nous allons dupliquer le thème clair (ThemeData.light
) et le modifier avec nos nouvelles couleurs. La duplication nous évitera de redéfinir toutes toutes toutes les couleurs.
class MyTheme { static final ThemeData defaultTheme = _buildTheme(); static ThemeData _buildTheme() { final ThemeData base = ThemeData.light(); return base.copyWith( accentColor: SecondaryColor, accentColorBrightness: Brightness.dark, primaryColor: PrimaryColor, primaryColorDark: PrimaryColorDark, primaryColorLight: PrimaryColorLight, primaryColorBrightness: Brightness.dark, buttonTheme: base.buttonTheme.copyWith( buttonColor: SecondaryColor, textTheme: ButtonTextTheme.primary, ), scaffoldBackgroundColor: Background, cardColor: Background, textSelectionColor: PrimaryColorLight, backgroundColor: Background, textTheme: base.textTheme.copyWith( title: base.textTheme.title.copyWith(color: TextColor), body1: base.textTheme.body1.copyWith(color: TextColor), body2: base.textTheme.body2.copyWith(color: TextColor) ), ); } }
And TADA! Voilà notre application légèrement plus jolie avec de jolies couleurs :)
Éteins la lumière, montre-moi ton coté sombre ♫
Maintenant, si vous aussi les applications toutes blanches vous font mal aux yeux, nous allons voir comment définir un thème sombre. Nous pourrions simplement définir des couleurs plus sombres lors de l'étape précédente, ou bien nous pouvons laissez le choix à l'utilisateur d'utiliser l'application claire ou sombre.
Pour cela, le package dynamic_theme
existe et simplifie la tache. Voyons donc comment l'utiliser.
Commençons par l'importer en ajoutant la ligne dynamic_theme: ^1.0.1
dans les dependencies
se trouvant dans le fichier pubspec.yaml
dependencies:
flutter:
sdk: flutter
dynamic_theme: ^1.0.1
Ensuite, de la même manière qu'à l'étape précédente, définissons un nouveau thème avec cette fois des couleurs plus sombres.
const DarkBackground = const Color(0xFF222727); class MyTheme { static final ThemeData darkTheme = _buildDarkTheme(); ... static ThemeData _buildDarkTheme() { final ThemeData base = ThemeData.dark(); return base.copyWith( accentColor: SecondaryColor, accentColorBrightness: Brightness.dark, primaryColor: PrimaryColor, primaryColorDark: PrimaryColorDark, primaryColorLight: PrimaryColorLight, primaryColorBrightness: Brightness.dark, buttonTheme: base.buttonTheme.copyWith( buttonColor: SecondaryColor, textTheme: ButtonTextTheme.primary, ), scaffoldBackgroundColor: DarkBackground, cardColor: DarkBackground, textSelectionColor: PrimaryColorLight, backgroundColor: Background, textTheme: base.textTheme.copyWith( title: base.textTheme.title.copyWith(color: TextColor), body1: base.textTheme.body1.copyWith(color: TextColor), body2: base.textTheme.body2.copyWith(color: TextColor) ), ); }
Puis dans la classe MyApp
, ajoutons les deux thèmes créés précédements en fonction de la luminosité choisie (brightness
) :
import 'package:dynamic_theme/dynamic_theme.dart'; class MyApp extends StatelessWidget { // This widget is the root of your application. @override Widget build(BuildContext context) { return new DynamicTheme( defaultBrightness: Brightness.light, data: (brightness) => brightness == Brightness.light ? MyTheme.defaultTheme : MyTheme.darkTheme, themedWidgetBuilder: (context, theme) { return MaterialApp( title: 'Flutter Demo Login', theme: theme, home: MyHomePage(title: 'Connexion'), ); }, ); } }
Maintenant, la partie intéressante : il nous faut permettre à l'utilisateur de choisir entre les deux thèmes. Pour cela, nous allons modifier l'AppBar de notre page pour ajouter un bouton permettant de changer le thème.
Ajoutons donc une méthode dans la classe _MyHomePageState
qui modifie la luminosité de l'application (brightness
) afin de modifier le thème de l'application.
void _turnOnOffLight() { DynamicTheme.of(context).setBrightness( Theme.of(context).brightness == Brightness.dark ? Brightness.light : Brightness.dark); }
Et finalement, ajoutons l'action dans la barre de navigation qui appellera cette méthode.
appBar: AppBar( title: Text(widget.title), actions: <Widget>[ IconButton(onPressed: _turnOnOffLight, icon: Icon(Icons.lightbulb_outline)) ], ),
And TADA! Voila notre application sombre (non Jonathan, pas comme le Titanic) !
I feel pretty, oh so pretty ♬
Et voila la comparaison. Finalement je ne suis pas sure que ce soit plus joli mais au moins nous avons pu investiguer les thèmes en Flutter.
Et pour le code source : le repo a été mis à jour et c'est par ici !
Commentaires