Sobes.tech
Middle

How flexible is Flutter in working with themes?

sobes.tech AI

Answer from AI

Flutter provides ThemeData for globally defining the visual properties of an application (colors, fonts, typography, etc.). Material widgets use Theme.of(context) to access the current theme.

Flexibility is provided at several levels:

  • Global theme: Defined in MaterialApp or CupertinoApp and applied to the entire app.
  • Local themes: Theme widgets can override the global theme for their child widgets. This is convenient for styling specific parts of the UI.
  • Theme extension: You can add your own attributes to ThemeData using ThemeExtension.
  • Adaptive themes: Easily switch between light and dark themes, reacting to system or user settings.
  • Customizable widgets: Create widgets that fully follow the system theme or have their own styles independent of the theme.

Example of using Theme:

// Defining a global theme
MaterialApp(
  theme: ThemeData(
    primarySwatch: Colors.blue,
    visualDensity: VisualDensity.adaptivePlatformDensity,
  ),
  home: HomePage(),
);

// Overriding theme for part of the UI
Theme(
  data: Theme.of(context).copyWith(
    primaryColor: Colors.green,
  ),
  child: ElevatedButtonTheme( // Example of using theme for a widget
    data: ElevatedButtonThemeData(
      style: ElevatedButton.styleFrom(
        backgroundColor: Colors.green, // Overriding button color
      ),
    ),
    child: ElevatedButton(
      onPressed: () {},
      child: Text('Green Button'),
    ),
  ),
);

Example of using ThemeExtension:

// Defining a theme extension
class MyThemeExtension extends ThemeExtension<MyThemeExtension> {
  const MyThemeExtension({
    required this.customColor,
  });

  final Color customColor;

  @override
  MyThemeExtension copyWith({Color? customColor}) {
    return MyThemeExtension(
      customColor: customColor ?? this.customColor,
    );
  }

  @override
  MyThemeExtension lerp(
      covariant ThemeExtension<MyThemeExtension>? other, double t) {
    if (other is! MyThemeExtension) {
      return this;
    }
    return MyThemeExtension(
      customColor: Color.lerp(customColor, other.customColor, t)!,
    );
  }
}

// Using the extension in ThemeData
MaterialApp(
  theme: ThemeData(
    extensions: <ThemeExtension<dynamic>>[
      MyThemeExtension(customColor: Colors.orange),
    ],
  ),
  home: Builder(
    builder: (context) {
      // Accessing extended theme data
      final myTheme = Theme.of(context).extension<MyThemeExtension>();
      return Scaffold(
        backgroundColor: myTheme?.customColor,
        body: Center(child: Text('Theme extension check')),
      );
    },
  ),
);