Search code examples
androidiosflutterdart

Flutter - Use Custom colors and themes in ThemeData


I want to use custom colors and themes in ThemeData. I know that I can define them in a separate file and import that file and use them. But I want those colors to work when changing the dark and light themes. Currently I have separate dark and light themes that I toggle. Is there anyway to define custom colors in dark and light ThemeData separately?

AppTheme.dart:

class AppTheme {
  AppTheme._();

  // Light Theme
  static final ThemeData lightTheme = ThemeData.light().copyWith(
    appBarTheme: AppBarTheme(
      color: Colors.grey[100],
      brightness: Brightness.light,
    ),
    scaffoldBackgroundColor: Colors.white,

    actionButtonColor: Colors.black, // Like this
  );

  // Dark Theme
  static final ThemeData darkTheme = ThemeData.dark().copyWith(
    appBarTheme: AppBarTheme(
      color: Colors.grey[850],
      brightness: Brightness.dark,
    ),
    scaffoldBackgroundColor: Colors.grey[900],

    actionButtonColor: Colors.red, // Like this
  );
}

App.dart

class App extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Dashboard(),
      theme: AppTheme.lightTheme,
      darkTheme: AppTheme.darkTheme,
      debugShowCheckedModeBanner: false,
    );
  }
}

Solution

  • I think you already have the answer in your own question, what you've been doing in the code sample is right, and is legal. And by the word legal, I mean the code will work and yield the result as you expected, of course, except for the part actionButtonColor property, because that property is not part of the ThemeData api.

    Or, if you are asking how to use that custom actionButtonColor property in your theme data, you can't. Because it is a predefined widget to use with material theming. That actionButton should just consume an existing property from the theme. But if you really need to do, you can use experimental extension methods in dart 2.7 like,

    extension MyColorScheme on ColorScheme {
      Color get actionButtonColor => const Colors.red;
    }
    
    ActionButtonComponent(
        color: Theme.of(context).colorScheme.actionButtonColor, 
    );
    

    But still, you won't be able to have a different colored scheme for another ThemeData like dark and light themes, when using with extension methods. You might want to look into this issue.

    I hope it helps.