How to dynamically change the theme in Flutter

Changing the theme at runtime and persisting those changes across restarts? No problem!

TLDR: I made a package which takes care of all of this, if you are interested on how it’s done keep reading.

How to do it.

Usually your entry point to the app looks like this:

If you want to change the theme of your app at compile time you can modify ThemeData . There is an attribute called Brightness which changes a bunch of colors from light to dark if set to Brightness.dark .

We want it to dynamically change that variable during runtime. We therefore introduce state to the top level widget.

Now, we have to access this state. Either by passing down a callback, writing a custom InheritedWidget or using the BuildContext to walk up the tree.

Passing down a callback is the most straight forward thing to do. But it also is the most annoying one. If the tree gets deep a lot of classes just pass the callback to its children. The logic is pretty simple though all that happens is:

Top widget implements a method which changes the brightness and calls setState()

Any child who has a reference to that method can invoke it.

An InheritedWidget would solve this problem by giving all the children access to the callback. You would still have to manage a callback, but this time there is no need to pass it all the way down.

The last viable option is searching the tree for the state. This one is pretty straight forward. We need a context to start the search, all we do is walk up the tree a search for a State which is of our type.

context.ancestorStateOfType(const TypeMatcher<YourState>());

Holding a static reference or global variable is a big no go, I won’t cover why in this post though.