Mastering Dark and Light Themes in Flutter with BLoC: A Comprehensive Guide (with Code Examples)
In this article, we will explore how to implement theme switching in Flutter using the BLoC (Business Logic Component) pattern. Theming is an essential aspect of app development, allowing us to provide a visually appealing user interface. With the BLoC pattern, we can separate the theme management logic from the UI components, resulting in a cleaner and more maintainable codebase. Let’s dive into the code and learn how to build a theme switcher using BLoC.
- Setting Up the Project: We begin by setting up a new Flutter project and importing the necessary packages, including
flutter_bloc
for BLoC implementation. - Creating the BLoC: Next, we create a
ThemeBloc
class that extendsBloc
fromflutter_bloc
. This class will handle the theme events and emit the appropriate theme states. We define two events,toggleDark
andtoggleLight
, to switch between dark and light themes.
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
enum ThemeEvent { toggleDark, toggleLight }
class ThemeBloc extends Bloc<ThemeEvent, ThemeState> {
ThemeBloc() : super(ThemeState.lightTheme);
@override
Stream<ThemeState> mapEventToState(ThemeEvent event) async* {
switch (event) {
case ThemeEvent.toggleDark:
yield ThemeState.darkTheme;
break;
case ThemeEvent.toggleLight:
yield ThemeState.lightTheme;
break;
}
}
}
3. Defining Theme States: We define a ThemeState
class that holds the ThemeData
for each theme. In this example, we have darkTheme
and lightTheme
as static properties. Customize these theme states based on your app's requirements.
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
class ThemeState {
final ThemeData themeData;
ThemeState(this.themeData);
static ThemeState get darkTheme =>
ThemeState(ThemeData.dark().copyWith(
// Customize dark theme properties
));
static ThemeState get lightTheme =>
ThemeState(ThemeData.light().copyWith(
// Customize light theme properties
));
}
4. Building the User Interface: In the main.dart
file, we wrap the MaterialApp
with a BlocProvider
widget, providing an instance of ThemeBloc
. Inside the BlocBuilder
, we retrieve the current theme state and update the app's theme accordingly.
// main.dart
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (context) => ThemeBloc(),
child: BlocBuilder<ThemeBloc, ThemeState>(
builder: (context, state) {
return MaterialApp(
theme: state.themeData,
home: HomePage(),
);
},
),
);
}
}
5.Handling Theme Switching: In the HomePage
widget, we access the ThemeBloc
instance using BlocProvider.of
. We display two buttons for switching between dark and light themes. On button press, we dispatch the corresponding theme event to the ThemeBloc
.
// home_page.dart
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
final themeBloc = BlocProvider.of<ThemeBloc>(context);
return Scaffold(
appBar: AppBar(
title: Text('Theme Switcher'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Switch between Dark and Light Themes:',
),
SizedBox(height: 20),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
RaisedButton(
onPressed: () => themeBloc.add(ThemeEvent.toggleDark),
child: Text('Dark'),
),
SizedBox(width: 10),
RaisedButton(
onPressed: () => themeBloc.add(ThemeEvent.toggleLight),
child: Text('Light'),
),
],
),
],
),
),
);
}
}
Conclusion: In this article, we explored how to implement theme switching in Flutter using the BLoC pattern. By following the code example, you can easily integrate a theme switcher into your Flutter app, providing users with the flexibility to switch between dark and light themes. The BLoC pattern allows for separation of concerns, making your codebase more maintainable and extensible. Experiment with customizing the themes and explore advanced features like persistence and dynamic theming. Happy theming with BLoC in Flutter!