Creating a Dynamic Theme Switcher in Flutter
In the past, customized devices were the epitome of coolness. With their unique colors, icons, and backgrounds, they made mobile devices stand out from the crowd. In this article, we’ll explore how to create a dynamic theme switcher in Flutter that allows users to select custom themes and even pick the dominant color from images.
Prerequisites
Before we dive into the tutorial, make sure you have the latest version of the Flutter SDK with null safety. Additionally, install the following dependencies:
flutter_colorpicker: v1.0.3
material_color_generator: v1.1.0
palette_generator: v0.3.3+2
provider: v6.0.3
shared_preferences: v2.0.15
Creating the Flutter App
Start by creating a new Flutter project using the command below:
flutter create <foldername>
Replace <foldername>
with your desired project name. This will create a standard counter project, which we won’t need. Instead, replace the code in main.dart
with the following:
“`dart
import ‘package:flutter/material.dart’;
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State
@override
Widget build(BuildContext context) {
return MaterialApp(
title: ‘Dynamic Theme Switcher’,
home: Scaffold(
appBar: AppBar(
title: Text(‘Dynamic Theme Switcher’),
),
body: Center(
child: Text(‘Hello, World!’),
),
),
);
}
}
“`
Restoring the Previous State using ChangeNotifier
To persist the current state of the app, we’ll use the shared_preferences
package. Create a new file called themes.dart
and add the following code:
“`dart
import ‘package:flutter/material.dart’;
import ‘package:sharedpreferences/sharedpreferences.dart’;
class AppTheme with ChangeNotifier {
static const String _key = ‘theme’;
SharedPreferences _prefs;
bool _darkTheme;
AppTheme() {
_initPrefs();
}
Future
_prefs = await SharedPreferences.getInstance();
_darkTheme = _prefs.getBool(key) ?? true;
notifyListeners();
}
void switchTheme(bool dark) {
darkTheme = dark;
_prefs.setBool(key, dark);
notifyListeners();
}
bool get darkTheme => _darkTheme;
}
“`
Flutter Project User Interface
The user interface will consist of two parts: selecting personal color choices for different theme properties and colors from images. Create two fields, a list containing the images, and six variables with type Color
(three each for two themes):
“`dart
class _MyAppState extends State
List
Colors.red,
Colors.blue,
Colors.green,
];
List
‘image1.jpg’,
‘image2.jpg’,
‘image3.jpg’,
];
Color _primaryColor;
Color _secondaryColor;
Color _accentColor;
Color _darkPrimaryColor;
Color _darkSecondaryColor;
Color _darkAccentColor;
}
“`
Selecting Color Choices from Theme Properties
Wrap the build
method in a ChangeNotifierProvider
. This will require using the provider
package:
dart
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider<AppTheme>(
create: (_) => AppTheme(),
child: Consumer<AppTheme>(
builder: (context, theme, child) {
return MaterialApp(
title: 'Dynamic Theme Switcher',
theme: theme.darkTheme ? _darkTheme : _lightTheme,
home: Scaffold(
appBar: AppBar(
title: Text('Dynamic Theme Switcher'),
),
body: Center(
child: Text('Hello, World!'),
),
),
);
},
),
);
}
Using the Palette Generator Flutter Package
To get the dominant color of the image, use the palette_generator
package. Create two instances, PaletteColor colors
and int _currentIndex
. Initialize them in an initState
function and call another function _updatePalettes
:
“`dart
class _MyAppState extends State
PaletteColor _colors;
int _currentIndex = 0;
@override
void initState() {
super.initState();
_updatePalettes();
}
void updatePalettes() {
for (var i = 0; i < _images.length; i++) {
PaletteGenerator.fromImageProvider(
AssetImage(images[i]),
size: Size(100, 100),
).then((palette) {
setState(() {
_colors = palette.dominantColor;
});
});
}
}
}
“`
Final Result
With the above code, you should now have a dynamic theme switcher in Flutter that allows users to select custom themes and even pick the dominant color from images.
Note: This is just a basic example and may require modifications to fit your specific needs.