Juan Sin Miedo
Juan Sin Miedo

Reputation: 161

How to change flutter theme colors when press a button

I'm trying to do an app with dynamic theme colors my idea is that when the user taps one button some parts of the app (buttons, appbar, themeData...) will change. But I'm not sure how to do it, I tried with some if conditions, and static variables.... but nothing works, any idea about how to do it?

I want to put 3 different themes for the app and here is the main file where I put the theme of the app:

void main() {
  runApp(CharlotApp());
}

class CharlotApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        debugShowCheckedModeBanner: false,
        title: 'Fluttter colors',
        theme: ThemeData(
          primaryColor: MyTheme.kPrimaryColor,
          accentColor: MyTheme.kAccentColor,
          visualDensity: VisualDensity.adaptivePlatformDensity,
        ),
        home: SplashScreen());
  }
}

Upvotes: 1

Views: 1920

Answers (1)

Gianluca Bettega
Gianluca Bettega

Reputation: 342

You can use the same aproach shared on this link:

final _themeGlobalKey = new GlobalKey(debugLabel: 'app_theme');

class AppTheme extends StatefulWidget {

  final child;

  AppTheme({
    this.child,
  }) : super(key: _themeGlobalKey);

  @override
  AppThemeState createState() => new AppThemeState();
}

class AppThemeState extends State<AppTheme> {

  ThemeData _theme = DEV_THEME;

  set theme(newTheme) {
    if (newTheme != _theme) {
      setState(() => _theme = newTheme);
    }
  }

  @override
  Widget build(BuildContext context) {
    return new ThemeChanger(
      appThemeKey: _themeGlobalKey,
      child: new Theme(
        data: _theme,
        child: widget.child,
      ),
    );
  }
}

class ThemeChanger extends InheritedWidget {

  static ThemeChanger of(BuildContext context) {
    return context.inheritFromWidgetOfExactType(ThemeChanger);
  }

  final ThemeData theme;
  final GlobalKey _appThemeKey;

  ThemeChanger({
    appThemeKey,
    this.theme,
    child
  }) : _appThemeKey = appThemeKey, super(child: child);

  set appTheme(AppThemeOption theme) {
    switch (theme) {
      case AppThemeOption.experimental:
        (_appThemeKey.currentState as AppThemeState)?.theme = EXPERIMENT_THEME;
        break;
      case AppThemeOption.dev:
        (_appThemeKey.currentState as AppThemeState)?.theme = DEV_THEME;
        break;
    }
  }

  @override
  bool updateShouldNotify(ThemeChanger oldWidget) {
    return oldWidget.theme == theme;
  }

}

In other class where you want to change theme

setState(() {
    ThemeChanger.of(context).appTheme = appThemeLight;
  });

Upvotes: 2

Related Questions