Thèmes et styles Flutter

Cette section présentera la configuration des thèmes dans Flutter, y compris les thèmes Material Design, les thèmes personnalisés et le mode sombre.


ThemeData - Thème de l'application

L'utilisation de ThemeData vous permet de configurer uniformément les couleurs de thème de l'application, les polices, les styles, et plus encore.

Exemple : Configuration du thème de l'application

void main() {
  runApp(
    MaterialApp(
      theme: ThemeData(
        // Couleur principale
        colorScheme: ColorScheme.fromSeed(
          seedColor: Colors.blue,
          brightness: Brightness.light,
        ),
        // Utiliser Material 3
        useMaterial3: true,
        // Police
        fontFamily: 'Roboto',
        // Thème de l'AppBar
        appBarTheme: const AppBarTheme(
          centerTitle: true,
          elevation: 0,
        ),
        // Thème des boutons
        elevatedButtonTheme: ElevatedButtonThemeData(
          style: ElevatedButton.styleFrom(
            padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12),
          ),
        ),
        // Thème du champ de saisie
        inputDecorationTheme: InputDecorationTheme(
          border: OutlineInputBorder(
            borderRadius: BorderRadius.circular(8),
          ),
          filled: true,
        ),
      ),
      home: const MyHomePage(),
    ),
  );
}

Theme.of - Utilisation du thème

Utilisez Theme.of(context) dans un Widget pour obtenir le thème actuel.

Exemple : Utilisation des couleurs du thème

class ThemedButton extends StatelessWidget {
  const ThemedButton({super.key});

  @override
  Widget build(BuildContext context) {
    // Obtenir le thème
    final theme = Theme.of(context);

    return Column(
      children: [
        // Utiliser la couleur du thème
        Conteneur(
          color: theme.colorScheme.primary,
          padding: const EdgeInsets.all(16),
          child: Text(
            'Couleur primaire',
            style: TextStyle(color: theme.colorScheme.onPrimary),
          ),
        ),
        const SizedBox(height: 16),
        // Utiliser la couleur secondaire
        Conteneur(
          color: theme.colorScheme.secondary,
          padding: const EdgeInsets.all(16),
          child: Text(
            'Couleur secondaire',
            style: TextStyle(color: theme.colorScheme.onSecondary),
          ),
        ),
        const SizedBox(height: 16),
        // Utiliser la couleur d'erreur
        Conteneur(
          color: theme.colorScheme.error,
          padding: const EdgeInsets.all(16),
          child: Text(
            'Couleur d'erreur',
            style: TextStyle(color: theme.colorScheme.onError),
          ),
        ),
      ],
    );
  }
}

Mode sombre

Exemple : Prise en charge du mode sombre

void main() {
  runApp(
    MaterialApp(
      theme: ThemeData(
        // Thème clair
        brightness: Brightness.light,
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue),
      ),
      darkTheme: ThemeData(
        // Thème sombre
        brightness: Brightness.dark,
        colorScheme: ColorScheme.fromSeed(
          seedColor: Colors.blue,
          brightness: Brightness.dark,
        ),
      ),
      // Activer les deux (facultatif)
      themeMode: ThemeMode.system,  // Selon les paramètres système
      // themeMode: ThemeMode.light // Forcer le mode clair
      // themeMode: ThemeMode.dark // Forcer le mode sombre
      home: const ThemeTogglePage(),
    ),
  );
}

// Basculer le thème
class ThemeTogglePage extends StatelessWidget {
  const ThemeTogglePage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Changement de thème')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            const Text('Thème actuel'),
            const SizedBox(height: 20),
            // Bouton de bascule du thème
            ElevatedButton(
              onPressed: () {
                final currentMode = Theme.of(context).brightness;
                if (currentMode == Brightness.light) {
                  // Passer en mode sombre
                  Theme.of(context).setThemeMode(ThemeMode.dark);
                } else {
                  // Passer en mode clair
                  Theme.of(context).setThemeMode(ThemeMode.light);
                }
              },
              child: const Text('Basculer le thème'),
            ),
          ],
        ),
      ),
    );
  }
}

Extensions de style personnalisées

Exemple : TextTheme personnalisé

⟦⟧ThemeData(
  textTheme: const TextTheme(
    // Texte d'affichage (titre principal)
    displayLarge: TextStyle(fontSize⟦⟧fontWeight⟦⟧FontWeight.: 57, fontWeight: FontWeight.w400),
    displayMedium: TextStyle(fontSize: 45, fontWeight: FontWeight.w400),
    displaySmall: TextStyle(fontSize: 36, fontWeight: FontWeight.w400),
    // Texte de titre
    headlineLarge: TextStyle(fontSize: 32, fontWeight: FontWeight.w400),
    headlineMedium: TextStyle(fontSize: 28, fontWeight: FontWeight.w400),
    headlineSmall: TextStyle(fontSize: 24, fontWeight: FontWeight.w400),
    // Texte de titre
    titleLarge: TextStyle(fontSize: 22, fontWeight: FontWeight.w500),
    titleMedium: TextStyle(fontSize: 16, fontWeight: FontWeight.w500),
    titleSmall: TextStyle(fontSize: 14, fontWeight: FontWeight.w500),
    // Texte du corps
    bodyLarge: TextStyle(fontSize: 16, fontWeight: FontWeight.w400),
    bodyMedium: TextStyle(fontSize: 14, fontWeight: FontWeight.w400),
    bodySmall: TextStyle(fontSize: 12, fontWeight: FontWeight.w400),
    // Texte d'étiquette
    labelLarge: TextStyle(fontSize: 14, fontWeight: FontWeight.w500),
    labelMedium: TextStyle(fontSize: 12, fontWeight: FontWeight.w500),
    labelSmall: TextStyle(fontSize: 11, fontWeight: FontWeight.w500),
  ),
)

L'utilisation de ThemeData pour gérer de manière centralisée les styles de l'application facilite le changement de thème et le maintien de la cohérence des styles, simplifiant la maintenance.

autres extensions