Hello fam 👋!
This tutorial shows the easiest way to setup adaptive themes in your flutter applications and instantly change them whenever user requests. Stick till then end for a better grasp at the concept!
Contents
- Required Packages 📦
- Initialization 🤩
- Theme change page 🎢
Required Packages 📦
Initialization 🤩
Here we are using the flex_color_scheme package for the themes, you can have your custom ones setup as you like. So the ease of explaining, this package fits the best!
In your main.dart
file, add the following code. Don't worry, It's well explained below!
void main() async {
WidgetsFlutterBinding.ensureInitialized();
// This is important
await Hive.initFlutter();
await Hive.openBox('user');
// Make use the theme key is set!
if (!Hive.box('user').containsKey('theme')) {
await Hive.box('user')
.put('theme', FlexScheme.values.indexOf(FlexScheme.dellGenoa));
}
runApp(const App());
}
class App extends StatefulWidget {
const App({super.key});
@override
AppState createState() => AppState();
}
class AppState extends State<App> {
@override
Widget build(BuildContext context) {
// This is a Widget that auto updates the state when data in the keys that are being watched are changed.
return ValueListenableBuilder(
// the box MUST exists, so look at the main function above
valueListenable: Hive.box('user').listenable(keys: ['theme']),
builder: (BuildContext context, Box box, Widget? widget) {
return MaterialApp(
title: 'FlutterSimplified',
// I am putting dart theme by default, you cant put that too as a listenable key and change on user request!
theme: FlexThemeData.dark(
scheme: FlexScheme.values[box.get('theme')], useMaterial3: true),
debugShowCheckedModeBanner: false,
home: const MyHomePage(), // A StatefuleWidget here
);
},
);
}
}
Theme change page 🎢
Now, let's make a page where user can select the theme they want!
Let's but that in theme_selector.dart
.
import 'package:flex_color_scheme/flex_color_scheme.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:hive_flutter/hive_flutter.dart';
class ThemeSelector extends StatefulWidget {
const ThemeSelector({super.key});
@override
State<ThemeSelector> createState() => _ThemeSelectorState();
}
class _ThemeSelectorState extends State<ThemeSelector> {
Box box = Hive.box('user');
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text(
'Imggy',
style: TextStyle(
fontWeight: FontWeight.w500,
),
),
leading: IconButton(
icon: const Icon(CupertinoIcons.back),
onPressed: () => Navigator.pop(context),
),
automaticallyImplyLeading: false,
),
body: ListView.builder(
itemCount: FlexScheme.values.length,
itemBuilder: (BuildContext context, int index) {
return ListTile(
leading: Icon(
CupertinoIcons.color_filter,
color: box.get('theme') == index ? Colors.blue : null,
),
title: Text(FlexScheme.values[index].toString().split('.').last),
onTap: () {
box.put('theme', index);
setState(() {});
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
content: Text('🍨 Theme has been selected!'),
));
Navigator.pop(context);
},
trailing:
box.get('theme') == index ? const Icon(Icons.check) : null,
);
},
),
);
}
}
The output should be something like this ->