ThemeExtension<T extends ThemeExtension<T>> class abstract

An interface that defines custom additions to a ThemeData object.

Learn more about ThemeExtension on the Flutter YouTube channel.

Typically used for custom colors. To use, subclass ThemeExtension, define a number of fields (e.g. Colors), and implement the copyWith and lerp methods. The latter will ensure smooth transitions of properties when switching themes.

This sample shows how to create and use a subclass of ThemeExtension that defines two colors.

To see it in action, copy and run this code snippet on DartPad.

import 'package:flutter/scheduler.dart';
import 'package:material_ui/material_ui.dart';

/// Flutter code sample for [ThemeExtension].

@immutable
class MyColors extends ThemeExtension<MyColors> {
  const MyColors({required this.brandColor, required this.danger});

  final Color? brandColor;
  final Color? danger;

  @override
  MyColors copyWith({Color? brandColor, Color? danger}) {
    return MyColors(
      brandColor: brandColor ?? this.brandColor,
      danger: danger ?? this.danger,
    );
  }

  @override
  MyColors lerp(MyColors? other, double t) {
    if (other is! MyColors) {
      return this;
    }
    return MyColors(
      brandColor: Color.lerp(brandColor, other.brandColor, t),
      danger: Color.lerp(danger, other.danger, t),
    );
  }

  // Optional
  @override
  String toString() => 'MyColors(brandColor: $brandColor, danger: $danger)';
}

void main() {
  // Slow down time to see lerping.
  timeDilation = 5.0;
  runApp(const ThemeExtensionExampleApp());
}

class ThemeExtensionExampleApp extends StatefulWidget {
  const ThemeExtensionExampleApp({super.key});

  @override
  State<ThemeExtensionExampleApp> createState() =>
      _ThemeExtensionExampleAppState();
}

class _ThemeExtensionExampleAppState extends State<ThemeExtensionExampleApp> {
  bool isLightTheme = true;

  void toggleTheme() {
    setState(() => isLightTheme = !isLightTheme);
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
        extensions: const <ThemeExtension<dynamic>>[
          MyColors(brandColor: Color(0xFF1E88E5), danger: Color(0xFFE53935)),
        ],
      ),
      darkTheme: ThemeData.dark().copyWith(
        extensions: <ThemeExtension<dynamic>>[
          const MyColors(
            brandColor: Color(0xFF90CAF9),
            danger: Color(0xFFEF9A9A),
          ),
        ],
      ),
      themeMode: isLightTheme ? .light : .dark,
      home: Home(isLightTheme: isLightTheme, toggleTheme: toggleTheme),
    );
  }
}

class Home extends StatelessWidget {
  const Home({
    super.key,
    required this.isLightTheme,
    required this.toggleTheme,
  });

  final bool isLightTheme;
  final void Function() toggleTheme;

  @override
  Widget build(BuildContext context) {
    final MyColors myColors = Theme.of(context).extension<MyColors>()!;
    return Material(
      child: Center(
        child: Row(
          mainAxisAlignment: .center,
          children: <Widget>[
            Container(width: 100, height: 100, color: myColors.brandColor),
            const SizedBox(width: 10),
            Container(width: 100, height: 100, color: myColors.danger),
            const SizedBox(width: 50),
            IconButton(
              icon: Icon(isLightTheme ? Icons.nightlight : Icons.wb_sunny),
              onPressed: toggleTheme,
            ),
          ],
        ),
      ),
    );
  }
}

Constructors

ThemeExtension()
Enable const constructor for subclasses.
const

Properties

hashCode int
The hash code for this object.
no setterinherited
runtimeType Type
A representation of the runtime type of the object.
no setterinherited
type Object
The extension's type.
no setter

Methods

copyWith() ThemeExtension<T>
Creates a copy of this theme extension with the given fields replaced by the non-null parameter values.
lerp(covariant ThemeExtension<T>? other, double t) ThemeExtension<T>
Linearly interpolate with another ThemeExtension object.
noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
toString() String
A string representation of this object.
inherited

Operators

operator ==(Object other) bool
The equality operator.
inherited