Avez-vous une question? (216) 97 656 803 hajjriadh@gmail.com
Flutter

La classe ThemeData dans Flutter

Un cours complet pour maîtriser La classe ThemeData dans Flutter.

0 chapitres 0 QCM Accès gratuit
  1. Objectifs

    • L'objectif de ce tutoriel est de comprendre comment utiliser et personnaliser la classe ThemeData dans 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.
  2. Introduction à ThemeData

    • Avant de commencer, il est important de noter que la classe ThemeData est 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 ThemeData est 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.
  3. Propriétés de base de la classe ThemeData

    • La classe ThemeData dans 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 classe ThemeData:
    1. 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é
          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)
            • 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.
    2. 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.
    3. É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).
    4. 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).
    5. Schéma de couleurs
      • colorScheme: Fournit un ensemble de couleurs cohérent utilisé dans toute l'application (recommandé par rapport à
      • primaryColor et accentColor).
    6. colorScheme.primary
    7. colorScheme.secondary
    8. colorScheme.background
    9. colorScheme.error
    10. Autres 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.
    11. 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,
          ),
        );
  4. 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 :
    1. Utilisation de Theme.of(context).propriété
      • Vous pouvez directement accéder aux propriétés du thème. Par exemple :
      • Container(
          color: Theme.of(context).primaryColor, // Accéder à primaryColor
          child: Text(
            'Texte avec couleur principale',
            style: TextStyle(color: Theme.of(context).primaryColor),
          ),
        ),
      • 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.
    2. Utilisation de Theme.of(context).colorScheme
      • Depuis Flutter 2.0, l’utilisation de ColorScheme est encouragée pour des thèmes plus cohérents.
      • Container(
          color: Theme.of(context).colorScheme.secondary, // Couleur d'accentuation
          child: Text(
            'Texte avec couleur secondaire',
            style: TextStyle(color: Theme.of(context).colorScheme.secondary),
          ),
        ),
      • 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.
    3. 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
            ),
      • 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'),
            ),
      • 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'),
              ),
            ),
    4. 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
          ),
    5. 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
          ),
    6. 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.
  5. Les propriétés d'accent de ThemeData sont obsolètes

    • Propriété accentColor: Utilisez colorScheme.secondaire à la place.
    • Le widget Theme dans Flutter

    • accentColor

        Le widget Theme dans Flutter

    • accentTextTheme

        Le widget Theme dans Flutter

  6. 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,
                      ),
                    ),
                  ],
                ),
              ),
            );
          }
        }
        

        Le widget Theme dans Flutter