Dynamic Theme in Flutter - Dark and Light Theme
Mighty
Posted on November 19, 2020
Adding Light and Dark theme for your app kind of become a mandatory thing in today's app world. Because most people prefer the dark theme over light theme because it is pretty comfortable for our eyes.
In this tutorial, we are going to implement a simple flutter app to switch between light and dart theme without much-complicated code.
First thing first, Let’s create a simple UI with a switch within it. This switch will change the variable called _light to true or false based on user interaction.
Switch(
value: _light,
onChanged: (toggle){
}),
In because we are changing the state of the App we need use stateful widget in here.
The simplest way of changing the light to dark is by changing the theme of the MaterialApp widget to light to dark. For that we need two themes like dark and light.
ThemeData _darkTheme = ThemeData(
accentColor: Colors.red,
brightness: Brightness.dark,
primaryColor: Colors.amber,
);
ThemeData _lightTheme = ThemeData(
accentColor: Colors.pink,
brightness: Brightness.light,
primaryColor: Colors.blue
);
When defining theme, you can select the accentColor and primaryColour based on your need . The important part is we have to mentioned the brightness whether is dark or light for each ThemeData class.
The next thing is based on the _light variable value, we can set the MaterialApp theme property to either light ThemeData object or dark one.
MaterialApp(
theme: _light ? _lightTheme : _darkTheme,
title: 'Material App')
Don’t forget to apply setState to Switch widget onChange callback.
Switch(
value: _light,
onChanged: (toggle){
setState(() {
_light = toggle;
});
})
Now you can see the app theme get changed nicely when you toggle the switch.
Hard cording Theme values
In because we are changing theme it bettor to not hardcoding some element like text and button colours. Because some of the hard corded colours may not be properly shows in dark or light theme.
Changing Button colours
You can set the default button color by setting buttonColor property. Also if you want more control of the button to change disable colour, height, padding etc. you can create a button theme.
ThemeData _darkTheme = ThemeData(
accentColor: Colors.red,
brightness: Brightness.dark,
primaryColor: Colors.amber,
buttonTheme: ButtonThemeData(
buttonColor: Colors.amber,
disabledColor: Colors.black
)
);
Adapt Theme based on the System Theme
If you have enabled the dark appearance of your phone you can set the default dark theme by specifying darkTheme property in MaterialApp widget. You can use the same dark Theme data object which we created previously. Now when you switch you phone to dark mode app will turn into dark mode automatically without changing. In this case switching from toggle not work in because we are forcefully changing the colour.
MaterialApp(
theme: _light ? _lightTheme : _darkTheme,
title: 'Material App',
darkTheme: _darkTheme)
Keep the selected theme persistently
If you want to keep the current theme selection even the user close the application you need to save the currently selected theme in a persistent way.
In the Flutter we can use shared preferences library to save current selected theme and check and set the theme when application get loaded.
Add the dependency and install
dependencies:
shared_preferences: ^0.5.7+3
flutter pub get
Import plugin to dart code
import 'package:shared_preferences/shared_preferences.dart';
Now you can use this plugin functionality. First lets create a two methods to save and retrieve the theme values
Future <SharedPreferences> _prefs = SharedPreferences.getInstance();
_saveTheme() async{
SharedPreferences pref = await _prefs;
pref.setBool('theme', _light);
}
_getTheme() async{
_lightF = _prefs.then((SharedPreferences prefs) {
return prefs.getBool('theme') != null ? prefs.getBool('theme') : true;
});
_light = await _lightF;
}
When the initState method get called you can call the _getTheme method to get the current saved theme.
@override
void initState() {
// TODO: implement initState
super.initState();
_getTheme();
}
Getting the values from the shared preferences and setting the value to shared preferences happen in an asynchronous way. Therefore we need to use the FutureBuilder widget to assign the theme after the retrieving part gets completed.
Therefore you can wrap the MaterialApp widget inside FutureBuilder widget and set the future property as a _lightF variable value.
Finally, you need to call the _saveTheme method when the user changes the switch from dark to light or vice versa.
Switch(value: _light, onChanged: (state){
setState(() {
_light = state;
});
_saveTheme();
}),
If the application already running, stop the running process and run the application again to see the changes
Dark and Light Theme - Part 1
Dark and Light Theme - Part 2
Posted on November 19, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.