Changing theme in runtime requires StatefulWidget, but isn't that ridiculously expensive?

Issue

I’ve recently finished a small side project in Flutter and when I tried to implement theme changing in runtime, most answers I came upon involved either putting my MaterialApp (which has the Theme) below a StatefulWidget or a Consumer<> of some sorts.

From what I understand, both these solutions proceed to redraw the entire widget tree below the MaterialApp when some change is encountered (either a state change in the case of the StatefulWidget or a change in whatever ChangeNotifier I provided to Consumer).

So my main questions are: Isn’t that very expensive and not recommended? Is my entire app widget tree being redrawn (assuming most of it is below the MaterialApp)?

And secondly: why aren’t the build methods of some of my own widgets deep below the MaterialApp tree being called? This would imply that the expensive rebuilds that the documentation implies aren’t actually being done. What gives?

Thanks in advance!

Solution

As I understand it if you wrap your MaterialApp in a Consumer that references a provider that only emits a value when your theme changes then this isn’t terribly inefficient. Yes, it will redraw the app when you change your theme, however it won’t redraw your app on every state change, only the change in that value. If you have a Provider that notifyListeners a lot, than you can use a Selector widget to only focus on your one value for theme.

However that said redrawing your app once when the user changes theme is not going to be expensive and will be done rather quickly. There is no way around redrawing your app on a theme change. If you are concerned you can use the Profiler tooling to test this, but you will find little to no issue on theme change.

Answered By – Gabe

Answer Checked By – David Marino (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *