Control the theme of your app like a pro — Flutter💙
We can change the theme from light to dark or vice-versa easily using package or State Management techniques. But let’s see how you can do this without using a single package!
Different users prefer different themes. Some love light themes while others love dark themes. Now, it becomes the developer’s responsibility to provide both themes in the app!
You can change the theme of your app programmatically using different packages. The main concept behind changing the theme is to get access to MaterialApp anywhere in the app and then change the theme and rebuild the MaterialApp. This can be done using different state management packages too like Provider. However, for a simple task, using packages is never a good choice! So let’s see how we can change the theme of the app programmatically without using a single package!
Bored of reading? Feel free to clone the repository from GitHub!
Step 1: Change MyApp to Stateful Widget
The first step will be to change the MyApp class to a Stateful Widget instead of a Stateless Widget. This will allow us to access the state class using the Inherited Widget concept and we will be able to rebuild the MaterialApp.
import 'package:flutter/material.dart';void main() => runApp(MyApp());class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Material App',
home: Home(),
);
}
}
Here, the Home() class will be our home page which we will see further in the article.
Step 2: Create a ThemeMode variable inside _MyAppState and provide the initial theme!
Now, create a variable that will set the theme to light or dark and set the initial theme to it. Also provide the themeData and darkTheme values to your MaterialApp!
class _MyAppState extends State<MyApp> {
ThemeMode _themeMode = ThemeMode.light;@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Material App',
themeMode: _themeMode,
theme: ThemeData(),
darkTheme: ThemeData.dark(),
home: Home(),
);
}
}
Step 3: Create a static function inside MyApp.
The next step is to create a static function called of which will take BuildContext as the argument and returns the _MyAppState class. It can be done as follows:
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();static _MyAppState? of(BuildContext context) => context.findAncestorStateOfType<_MyAppState>();
}
Step 4: Create a function to change the theme in _MyAppState
Let’s create a function that will change the theme of the app. It will be a simple function that takes the new ThemeMode as its parameter and assign it to our local _themeMode variable.
void changeTheme(ThemeMode themeMode) {
setState(() {
_themeMode = themeMode;
});
}
That’s it for the main. dart file, let’s see how it looks like:
Step 5: Let’s create our home.dart which will have a switch in the centre!
import 'package:flutter/material.dart';
import 'package:theme_example/main.dart';class Home extends StatefulWidget {
const Home({Key? key}) : super(key: key);@override
_HomeState createState() => _HomeState();
}class _HomeState extends State<Home> {
bool _value = false;@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Switch(
value: _value,
onChanged: (value) {},
),
),
);
}
}
The code looks pretty simple, we just have a small switch in the centre of the screen which will change the theme of our app. Let’s add the functionality for it now!
Step 6: Call changeTheme function (created in _MyAppState) using the static function (created in MyApp)
setState(() {
_value = value;
if (_value)
MyApp.of(context)!.changeTheme(ThemeMode.dark);
else
MyApp.of(context)!.changeTheme(ThemeMode.light);
});
Let’s see how home.dart looks like:
That’s it! You have successfully implemented the theme changing programmatically without any packages!
Output:
Hope you enjoyed this article!
Don’t stop, until you are breathing!💙
- Abhishek Doshi