As more users come to expect a customizable viewing experience in their apps, providing a light/dark mode toggle has become a staple in app development. Flutter, with its rich set of widgets and properties, makes this not only possible but pleasantly straightforward. In this post, we'll walk through how to add a theme toggle to your Flutter app, complete with intuitive sun and moon icons.
Let's start by setting the stage with our main function and DarkLightApp
widget. We launch our app with runApp(const DarkLightApp())
, which serves as the entry point. Our DarkLightApp
is a StatefulWidget
because theme toggling will change the app's state.
void main() {
runApp(const DarkLightApp());
}
class DarkLightApp extends StatefulWidget {
const DarkLightApp({super.key});
@override
_DarkLightAppState createState() => _DarkLightAppState();
}
Next, we define _DarkLightAppState
to hold our theme state. We initialize our theme mode to dark with ThemeMode _themeMode = ThemeMode.dark
.
class _DarkLightAppState extends State<DarkLightApp> {
ThemeMode _themeMode = ThemeMode.dark;
...
}
Our _toggleTheme
function takes a boolean isOn
and sets the theme mode to light or dark, depending on the switch's position. This is where setState
shines, notifying the framework to redraw the widget with the updated theme mode.
void _toggleTheme(bool isOn) {
setState(() {
_themeMode = isOn ? ThemeMode.light : ThemeMode.dark;
});
}
In the build
method, we craft our MaterialApp
, which now includes the theme toggling logic. By setting debugShowCheckedModeBanner
to false
, we ensure a clean UI without the debug tag.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Dark/Light App',
debugShowCheckedModeBanner: false,
...
);
}
For our themes, we define both darkTheme
and theme
. The darkTheme
uses Brightness.dark
, while theme
uses a color scheme seeded with blue for light mode.
darkTheme: ThemeData(
brightness: Brightness.dark,
),
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue),
useMaterial3: true,
),
Now, the star of our UI: the Scaffold
within MaterialApp
's home
. The AppBar
not only holds our title but also a Row
of Icons
and a Switch
that control the theme mode.
home: Scaffold(
appBar: AppBar(
title: const Text('Dark/Light App'),
actions: [
Icon(Icons.dark_mode),
Switch(
value: _themeMode == ThemeMode.light,
onChanged: _toggleTheme,
),
Icon(Icons.light_mode),
],
),
body: const Center(
child: Text('Hello World'),
),
),
The Switch
widget toggles the theme mode and, flanked by the sun (Icons.light_mode
) and moon (Icons.dark_mode
) icons, provides a clear visual cue for its function.
By using Flutter's ThemeData
and ThemeMode
, we created a seamless way to allow users to switch between light and dark themes. This not only caters to their visual preferences but also can help save battery life on OLED screens and reduce eye strain in low-light conditions.
Implementing a theme toggle in your Flutter app not only enhances the user experience but also showcases the dynamic capabilities of your app. With just a few lines of code, you can give your users the power to choose their preferred theme, making your app more inclusive and user-friendly.
Happy coding!