La classe ThemeData dans Flutter
Sommaire
- 1- Objectifs
- 2- Introduction à ThemeData
- 3- Propriétés de base de la classe ThemeData
- 3.1- Couleurs
- 3.2- Typographie
- 3.3- Éléments interactifs
- 3.4- Effets visuels
- 3.5- Schéma de couleurs
- 3.6- Autres styles
- 3.7- Exemple de définition de ThemeData
- 4- Accéder aux couleurs définies dans le thème (
ThemeData
) - 4.1- Utilisation de
Theme.of(context).propriété
- 4.2- Utilisation de Theme.of(context).colorScheme
- 4.3- Utilisation dans les widgets spécifiques
- 4.4- Utilisation dans le texte avec TextStyle
- 4.5- Récupérer des couleurs personnalisées définies dans ThemeData
- 4.6- Utiliser les couleurs du thème dans d'autres fichiers
- 5- Les propriétés d'accent de
ThemeData
sont obsolètes - 5.1- accentColor
- 5.2- accentTextTheme
- 6- Application
- 6.1.1- Cours Flutter
La classe ThemeData dans Flutter
-
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. -
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.
-
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 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.
-
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 àcolorScheme.primary
colorScheme.secondary
colorScheme.background
colorScheme.error
-
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.-
Exemple de définition de ThemeData
-
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.-
Utilisation de Theme.of(context).colorScheme
- Depuis Flutter 2.0, l’utilisation de
ColorScheme
est 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.-
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 :
- b. ElevatedButton
- Pour les boutons, les couleurs sont basées sur colorScheme.secondary :
- c. Card
- 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 :
-
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 :
- Ajouter dans le thème :
- Accéder à l’extension :
-
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
ThemeData
sont 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.
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 :
primaryColor et accentColor).
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,
),
);
Container(
color: Theme.of(context).primaryColor, // Accéder à primaryColor
child: Text(
'Texte avec couleur principale',
style: TextStyle(color: Theme.of(context).primaryColor),
),
),
Container(
color: Theme.of(context).colorScheme.secondary, // Couleur d'accentuation
child: Text(
'Texte avec couleur secondaire',
style: TextStyle(color: Theme.of(context).colorScheme.secondary),
),
),
AppBar(
title: Text('Exemple AppBar'),
backgroundColor: Theme.of(context).primaryColor, // Couleur principale
),
ElevatedButton(
onPressed: () {},
style: ElevatedButton.styleFrom(
backgroundColor: Theme.of(context).colorScheme.secondary, // Couleur d'accentuation
),
child: Text('Bouton'),
),
Card(
color: Theme.of(context).cardColor, // Couleur de la carte
child: Padding(
padding: EdgeInsets.all(16.0),
child: Text('Ceci est une carte'),
),
),
Text(
'Texte personnalisé',
style: TextStyle(color: Theme.of(context).primaryColor), // Couleur principale
),
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),
);
}
}
theme: ThemeData(
extensions: >[
CustomColors(customBackground: Colors.lightGreen),
],
),
final customColors = Theme.of(context).extension();
Container(
color: customColors?.customBackground, // Couleur personnalisée
),
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,
),
),
],
),
),
);
}
}