DEV Community

Akash Pattnaik
Akash Pattnaik

Posted on

Active theme switch in flutter

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
        );
      },
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

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,
          );
        },
      ),
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

The output should be something like this ->

Top comments (0)