Flutter Themes and Styling

This section will introduce theme configuration in Flutter, including Material Design themes, custom themes, and dark mode.


ThemeData - App Theme

Using ThemeData allows you to uniformly configure the app's theme colors, fonts, styles, and more.

Example: Configuring the App Theme

void main() {
  runApp(
    MaterialApp(
      theme: ThemeData(
        // Primary color
        colorScheme: ColorScheme.fromSeed(
          seedColor: Colors.blue,
          brightness: Brightness.light,
        ),
        // Use Material 3
        useMaterial3: true,
        // Font
        fontFamily: 'Roboto',
        // AppBar theme
        appBarTheme: const AppBarTheme(
          centerTitle: true,
          elevation: 0,
        ),
        // Button theme
        elevatedButtonTheme: ElevatedButtonThemeData(
          style: ElevatedButton.styleFrom(
            padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12),
          ),
        ),
        // Input field theme
        inputDecorationTheme: InputDecorationTheme(
          border: OutlineInputBorder(
            borderRadius: BorderRadius.circular(8),
          ),
          filled: true,
        ),
      ),
      home: const MyHomePage(),
    ),
  );
}

Theme.of - Using the Theme

Use Theme.of(context) in a Widget to get the current theme.

Example: Using Theme Colors

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

  @override
  Widget build(BuildContext context) {
    // Get theme
    final theme = Theme.of(context);

    return Column(
      children: [
        // Use theme color
        Container(
          color: theme.colorScheme.primary,
          padding: const EdgeInsets.all(16),
          child: Text(
            'Primary color',
            style: TextStyle(color: theme.colorScheme.onPrimary),
          ),
        ),
        const SizedBox(height: 16),
        // Use secondary color
        Container(
          color: theme.colorScheme.secondary,
          padding: const EdgeInsets.all(16),
          child: Text(
            'Secondary color',
            style: TextStyle(color: theme.colorScheme.onSecondary),
          ),
        ),
        const SizedBox(height: 16),
        // Use error color
        Container(
          color: theme.colorScheme.error,
          padding: const EdgeInsets.all(16),
          child: Text(
            'Error color',
            style: TextStyle(color: theme.colorScheme.onError),
          ),
        ),
      ],
    );
  }
}

Dark Mode

Example: Dark Mode Support

void main() {
  runApp(
    MaterialApp(
      theme: ThemeData(
        // Light theme
        brightness: Brightness.light,
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue),
      ),
      darkTheme: ThemeData(
        // Dark theme
        brightness: Brightness.dark,
        colorScheme: ColorScheme.fromSeed(
          seedColor: Colors.blue,
          brightness: Brightness.dark,
        ),
      ),
      // Enable both (optional)
      themeMode: ThemeMode.system,  // Based on system settings
      // themeMode: ThemeMode.light // Force light mode
      // themeMode: ThemeMode.dark // Force dark mode
      home: const ThemeTogglePage(),
    ),
  );
}

// Toggle theme
class ThemeTogglePage extends StatelessWidget {
  const ThemeTogglePage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Theme Switch')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            const Text('Current Theme'),
            const SizedBox(height: 20),
            // Toggle theme button
            ElevatedButton(
              onPressed: () {
                final currentMode = Theme.of(context).brightness;
                if (currentMode == Brightness.light) {
                  // Switch to dark mode
                  Theme.of(context).setThemeMode(ThemeMode.dark);
                } else {
                  // Switch to light mode
                  Theme.of(context).setThemeMode(ThemeMode.light);
                }
              },
              child: const Text('Toggle Theme'),
            ),
          ],
        ),
      ),
    );
  }
}

Custom Style Extensions

Example: Custom TextTheme

ThemeData(
  textTheme: const TextTheme(
    // Display text (headline)
    displayLarge: TextStyle(fontSize: 57, fontWeight: FontWeight.w400),
    displayMedium: TextStyle(fontSize: 45, fontWeight: FontWeight.w400),
    displaySmall: TextStyle(fontSize: 36, fontWeight: FontWeight.w400),
    // Title text
    headlineLarge: TextStyle(fontSize: 32, fontWeight: FontWeight.w400),
    headlineMedium: TextStyle(fontSize: 28, fontWeight: FontWeight.w400),
    headlineSmall: TextStyle(fontSize: 24, fontWeight: FontWeight.w400),
    // Title text
    titleLarge: TextStyle(fontSize: 22, fontWeight: FontWeight.w500),
    titleMedium: TextStyle(fontSize: 16, fontWeight: FontWeight.w500),
    titleSmall: TextStyle(fontSize: 14, fontWeight: FontWeight.w500),
    // Body text
    bodyLarge: TextStyle(fontSize: 16, fontWeight: FontWeight.w400),
    bodyMedium: TextStyle(fontSize: 14, fontWeight: FontWeight.w400),
    bodySmall: TextStyle(fontSize: 12, fontWeight: FontWeight.w400),
    // Label text
    labelLarge: TextStyle(fontSize: 14, fontWeight: FontWeight.w500),
    labelMedium: TextStyle(fontSize: 12, fontWeight: FontWeight.w500),
    labelSmall: TextStyle(fontSize: 11, fontWeight: FontWeight.w500),
  ),
)

Using ThemeData to centrally manage app styles makes it easy to switch themes and maintain style consistency, simplifying maintenance.

other extensions