Objectifs
- L'objectif de ce tutoriel est de comprendre comment utiliser et personnaliser la classe
ThemeDatadans Flutter pour créer des thèmes cohérents et adaptables à toute une application. Vous apprendrez à définir des thèmes globaux, à appliquer des styles de texte et à intégrer des thèmes sombres.
- L'objectif de ce tutoriel est de comprendre comment utiliser et personnaliser la classe
Introduction à ThemeData
- Avant de commencer, il est important de noter que la classe
ThemeDataest la classe la plus importante pour le style et la thématisation dans Flutter. Cette classe fournit des propriétés permettant de personnaliser les couleurs, les polices et les tailles dans toute l'application. - Lorsque vous créez une application Flutter, elle est livrée avec un thème bleu clair par défaut appliqué à l'ensemble de l'application. Ce thème par défaut est une instance de la classe ThemeData.
- La classe
ThemeDataest un composant central pour gérer les couleurs, les styles et les polices à travers une application Flutter. Elle vous permet de définir un thème global qui est appliqué de manière cohérente. - Rôle de ThemeData
- Couleurs principales : Définit les couleurs comme celles de l'AppBar ou des boutons.
- Styles de texte: Uniformise les styles de police dans toute l'application.
- Personnalisation facile: Permet de modifier l'apparence de l'application en un seul endroit.
- Couleurs principales : Définit les couleurs comme celles de l'AppBar ou des boutons.
- Avant de commencer, il est important de noter que la classe
Propriétés de base de la classe ThemeData
- La classe
ThemeDatadans Flutter est utilisée pour définir les thèmes globaux d'une application, tels que les couleurs, les polices, les styles de texte, et bien plus. Voici un aperçu des propriétés de base de la classeThemeData:
Couleurs
primaryColor: Couleur principale utilisée dans l'application.accentColor (remplacée par colorScheme.secondary): Couleur d'accentuation, utilisée pour les éléments interactifs.backgroundColor: Couleur d'arrière-plan.scaffoldBackgroundColor: Couleur de fond de l'écran.canvasColor: Couleur pour les widgets comme les menus contextuels et les tiroirs.cardColor: Couleur des cartes.dividerColor: Couleur des séparateurs ou des lignes.- Activité
- 1. Couleur principale (PrimaryColor)
- Modifiez la couleur principale (primaryColor) de l'application en vert (Colors.green). Observez les changements sur les éléments utilisant cette couleur.
- 2. Couleur d'accentuation (AccentColor)
- Changez la couleur d'accentuation (colorScheme.secondary) en rouge (Colors.red). Notez où cette couleur est appliquée.
- 3. Couleur du Drawer
- Modifiez la couleur de fond du Drawer (canvasColor) pour qu'elle devienne jaune clair (Colors.yellow[100]).
- 4. Couleur des cartes (CardColor)
- Personnalisez la couleur des cartes (cardColor) en gris clair (Colors.grey[300]).
- 5. Couleur des séparateurs (DividerColor)
- Changez la couleur des séparateurs (dividerColor) en bleu marine (Colors.blue[900]).
- 6. Couleur de fond du Scaffold
- Modifiez la couleur de fond de l'écran (scaffoldBackgroundColor) en une couleur personnalisée, comme rose clair (Colors.pink[50]).
- 7. Personnalisation de l'AppBar
- Ajoutez un icône (e.g., Icons.home) sur la gauche du titre dans l'AppBar.
- Changez la couleur du texte du titre en blanc.
- 8. Personnalisation du bouton (ElevatedButton)
- Modifiez la couleur du texte du bouton en noir.
- Modifiez la couleur de fond du bouton pour qu'elle corresponde à la couleur principale de l'application.
- 9. Couleur de l'en-tête du Drawer
- Changez la couleur de l'en-tête du Drawer pour utiliser une couleur dégradée en modifiant la propriété decoration du DrawerHeader.
Recopier le code suivant
import 'package:flutter/material.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( theme: ThemeData( primaryColor: Colors.blue, // Couleur principale scaffoldBackgroundColor: Colors.white, // Couleur de fond de l'écran canvasColor: Colors.lightBlue[100], // Couleur pour les menus contextuels et Drawer (bleu ciel) cardColor: Colors.white, // Couleur des cartes dividerColor: Colors.black38, // Couleur des séparateurs ou lignes colorScheme: ColorScheme.fromSwatch().copyWith( secondary: Colors.orange, // Couleur d'accentuation surface: Colors.grey[200], // Couleur d'arrière-plan pour certains composants ), ), home: HomePage(), ); } } class HomePage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Exemple Thème Flutter'), backgroundColor: Theme.of(context).primaryColor, // Utilisation de primaryColor ), body: SingleChildScrollView( child: Container( color: Theme.of(context).colorScheme.surface, // Utilisation de surface comme arrière-plan padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Couleur principale : primaryColor', style: TextStyle(color: Theme.of(context).primaryColor), ), SizedBox(height: 10), Text( 'Couleur d\'accentuation : colorScheme.secondary', style: TextStyle(color: Theme.of(context).colorScheme.secondary), ), SizedBox(height: 20), ElevatedButton( onPressed: () {}, style: ElevatedButton.styleFrom( backgroundColor: Theme.of(context).colorScheme.secondary, // Bouton avec accentColor ), child: Text('Bouton d\'accentuation'), ), SizedBox(height: 20), Card( color: Theme.of(context).cardColor, // Utilisation de cardColor child: Padding( padding: const EdgeInsets.all(16.0), child: Text('Ceci est une carte'), ), ), SizedBox(height: 20), Divider( color: Theme.of(context).dividerColor, // Utilisation de dividerColor ), SizedBox(height: 20), DrawerExample(), ], ), ), ), drawer: Drawer( child: Container( color: Theme.of(context).canvasColor, // Couleur bleu ciel pour le Drawer child: ListView( children: const [ DrawerHeader( child: Text('Menu contextuel', style: TextStyle(color: Colors.white)), decoration: BoxDecoration(color: Colors.blue), // Couleur d'en-tête du Drawer ), ListTile( title: Text('Option 1'), ), ListTile( title: Text('Option 2'), ), ], ), ), ), ); } } class DrawerExample extends StatelessWidget { @override Widget build(BuildContext context) { return ElevatedButton( onPressed: () { Scaffold.of(context).openDrawer(); }, child: Text('Ouvrir le Drawer'), ); } }Questions proposées :
- 1. Couleur principale (PrimaryColor)
Typographie
textTheme: Définit les styles pour les textes globaux.primaryTextTheme: Style de texte lié au primaryColor.accentTextTheme: Style de texte lié à la couleur d'accentuation.fontFamily: Définit une famille de polices globale.
Éléments interactifs
buttonTheme: Configure le style des boutons.textButtonTheme: Définit le thème pour les TextButton.elevatedButtonTheme: Style des ElevatedButton.outlinedButtonTheme: Thème des OutlinedButton.floatingActionButtonTheme: Style des boutons d'action flottants.iconTheme: Définit le style des icônes globalement.appBarTheme: Thème des barres d'application (AppBar).
Effets visuels
brightness: Définit le mode lumineux ou sombre (valeurs : Brightness.light ou Brightness.dark).shadowColor: Couleur des ombres dans l'application.dividerTheme: Personnalisation des séparateurs (Divider).
Schéma de couleurs
colorScheme: Fournit un ensemble de couleurs cohérent utilisé dans toute l'application (recommandé par rapport à
primaryColor et accentColor).colorScheme.primarycolorScheme.secondarycolorScheme.backgroundcolorScheme.errorAutres styles
inputDecorationTheme: Style des champs de saisie.snackBarTheme: Thème des messages SnackBar.sliderTheme: Thème des Slider.dialogTheme: Style des boîtes de dialogue (AlertDialog).checkboxTheme: Style des Checkbox.radioTheme: Thème des boutons radio.
Exemple de définition de ThemeData
ThemeData myTheme = ThemeData( primaryColor: Colors.blue, accentColor: Colors.amber, backgroundColor: Colors.white, textTheme: TextTheme( bodyText1: TextStyle(fontSize: 16, color: Colors.black), headline1: TextStyle(fontSize: 24, fontWeight: FontWeight.bold), ), appBarTheme: AppBarTheme( color: Colors.blue, titleTextStyle: TextStyle(color: Colors.white, fontSize: 20), ), floatingActionButtonTheme: FloatingActionButtonThemeData( backgroundColor: Colors.amber, ), colorScheme: ColorScheme.fromSwatch().copyWith( secondary: Colors.amber, ), );
- La classe
Accéder aux couleurs définies dans le thème (
ThemeData)- Dans Flutter, vous pouvez accéder aux couleurs définies dans le thème (ThemeData) à l'aide de Theme.of(context), qui renvoie une instance de ThemeData associée au contexte actuel. Voici plusieurs méthodes pour accéder et utiliser ces couleurs dans votre application :
-
Utilisation de
Theme.of(context).propriété- Vous pouvez directement accéder aux propriétés du thème. Par exemple :
- Propriétés courantes :
primaryColor: Couleur principale.canvasColor: Couleur utilisée pour le fond du Drawer et des menus contextuels.cardColor: Couleur utilisée pour les cartes.dividerColor: Couleur des lignes de séparation.scaffoldBackgroundColor: Couleur d'arrière-plan de l'écran.
Container( color: Theme.of(context).primaryColor, // Accéder à primaryColor child: Text( 'Texte avec couleur principale', style: TextStyle(color: Theme.of(context).primaryColor), ), ), Utilisation de Theme.of(context).colorScheme
- Depuis Flutter 2.0, l’utilisation de
ColorSchemeest encouragée pour des thèmes plus cohérents. - Propriétés courantes dans ColorScheme :
primary: Couleur principale.secondary: Couleur d'accentuation.surface: Couleur de surface (par exemple, arrière-plan d’une carte).background: Couleur d'arrière-plan.onPrimary, onSecondary: Couleurs du texte ou des icônes affichés sur primary ou secondary.
Container( color: Theme.of(context).colorScheme.secondary, // Couleur d'accentuation child: Text( 'Texte avec couleur secondaire', style: TextStyle(color: Theme.of(context).colorScheme.secondary), ), ),- Depuis Flutter 2.0, l’utilisation de
Utilisation dans les widgets spécifiques
- Certains widgets utilisent les couleurs du thème automatiquement. Vous pouvez personnaliser leur style en fonction du thème.
- a. AppBar
- L'AppBar utilise primaryColor par défaut :
AppBar( title: Text('Exemple AppBar'), backgroundColor: Theme.of(context).primaryColor, // Couleur principale ),
- L'AppBar utilise primaryColor par défaut :
- b. ElevatedButton
- Pour les boutons, les couleurs sont basées sur colorScheme.secondary :
ElevatedButton( onPressed: () {}, style: ElevatedButton.styleFrom( backgroundColor: Theme.of(context).colorScheme.secondary, // Couleur d'accentuation ), child: Text('Bouton'), ),
- Pour les boutons, les couleurs sont basées sur colorScheme.secondary :
- c. Card
- Les cartes utilisent cardColor par défaut :
Card( color: Theme.of(context).cardColor, // Couleur de la carte child: Padding( padding: EdgeInsets.all(16.0), child: Text('Ceci est une carte'), ), ),
- Les cartes utilisent cardColor par défaut :
Utilisation dans le texte avec TextStyle
- Les couleurs du thème peuvent être appliquées directement au texte :
Text( 'Texte personnalisé', style: TextStyle(color: Theme.of(context).primaryColor), // Couleur principale ),
- Les couleurs du thème peuvent être appliquées directement au texte :
Récupérer des couleurs personnalisées définies dans ThemeData
- Vous pouvez ajouter des couleurs personnalisées dans ThemeData via l'objet extensions :
- Définir une extension personnalisée :
class CustomColors extends ThemeExtension{ final Color? customBackground; CustomColors({this.customBackground}); @override CustomColors copyWith({Color? customBackground}) { return CustomColors(customBackground: customBackground ?? this.customBackground); } @override CustomColors lerp(ThemeExtension ? other, double t) { if (other is! CustomColors) return this; return CustomColors( customBackground: Color.lerp(customBackground, other.customBackground, t), ); } } - Ajouter dans le thème :
theme: ThemeData( extensions:>[ CustomColors(customBackground: Colors.lightGreen), ], ), - Accéder à l'extension :
final customColors = Theme.of(context).extension(); Container( color: customColors?.customBackground, // Couleur personnalisée ),
Utiliser les couleurs du thème dans d'autres fichiers
- Si vous êtes dans un widget sans accès au BuildContext :
- Passez
Theme.of(context).propriétéen paramètre au widget. - Ou utilisez un widget héritant du contexte, comme un parent Scaffold ou Theme.
Les propriétés d'accent de
ThemeDatasont obsolètes- Propriété accentColor: Utilisez colorScheme.secondaire à la place.
accentColor

accentTextTheme


Application
- Voici quelques exercices pour vous aider à comprendre comment utiliser ThemeData dans Flutter:
- Créez une nouvelle application Flutter avec un thème sombre en utilisant ThemeData.
- Modifiez la couleur de fond de l'application en utilisant les propriétés de couleur dans ThemeData.
- Ajoutez une police personnalisée à l'application en utilisant la propriété textTheme dans ThemeData.
- Modifiez les couleurs des boutons en utilisant les propriétés buttonTheme et buttonColor dans ThemeData.
- Créez plusieurs thèmes différents pour l'application en utilisant des instances de ThemeData distinctes et en les switchant selon les préférences de l'utilisateur.
import 'package:flutter/material.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( theme: ThemeData( // Définit la luminosité et les couleurs par défaut. brightness: Brightness.light, primaryColor: Colors.indigo, // Définit la famille de polices par défaut. fontFamily: 'Montserrat', // Définit le `TextTheme` par défaut. Utilisez ceci pour spécifier la valeur par défaut // style de texte pour les titres, les titres, les corps de texte, etc. textTheme: TextTheme( headline1: TextStyle( fontSize: 36.0, fontWeight: FontWeight.bold, color: Colors.indigo[900], ), headline2: const TextStyle( fontSize: 28.0, fontWeight: FontWeight.bold, color: Color.fromARGB(255, 126, 26, 109), ), bodyText1: TextStyle( fontSize: 16.0, color: Colors.grey[800], fontWeight: FontWeight.normal, ), bodyText2: TextStyle( fontSize: 14.0, color: Colors.grey[600], fontWeight: FontWeight.normal, ), ), buttonTheme: ButtonThemeData( textTheme: ButtonTextTheme.primary, buttonColor: Colors.indigo[900], shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10.0), ), ), appBarTheme: AppBarTheme( color: Colors.indigo[50], textTheme: TextTheme( headline6: TextStyle( fontSize: 20.0, fontWeight: FontWeight.bold, color: Colors.indigo[900], ), ), ), visualDensity: VisualDensity.adaptivePlatformDensity, ), home: HomePage(), ); } } class HomePage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Mon thème personnalisé'), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Padding( padding: EdgeInsets.all(10), child: Text( 'Bienvenue dans mon application personnalisée!', style: Theme.of(context).textTheme.headline1, ), ), Padding( padding: EdgeInsets.all(10), child: Text( 'Bienvenue dans mon application personnalisée!', style: Theme.of(context).textTheme.headline2, ), ), Padding( padding: EdgeInsets.all(10), child: Text( 'Bienvenue dans mon application personnalisée!', style: Theme.of(context).textTheme.bodyText1, ), ), Padding( padding: EdgeInsets.all(10), child: Text( 'Bienvenue dans mon application personnalisée!', style: Theme.of(context).textTheme.bodyText2, ), ), ], ), ), ); } }
- Voici quelques exercices pour vous aider à comprendre comment utiliser ThemeData dans Flutter: