Categories
Development London Bus Pal

Dark mode: this is why I love Flutter

Spread the love

I’ve seen all of the hype around dark mode lately and I knew that at some point, I’d probably have to jump on that band wagon. But, it isn’t on my priority list as I’ve promised my users something else.

As I was wasting time yesterday, I saw a Youtube video about the dark mode craze and I thought, let’s give it a go – I needed a distraction anyway.

Flutter theme

  ThemeData theme = ThemeData(
      primarySwatch: Colors.red,
      primaryColorDark: Colors.red.shade700,
      secondaryHeaderColor: Colors.white,
      accentColor: Colors.orangeAccent,
    );

I previously pulled out my theme into a separate variable as I was playing around to make sure that my entire app respected the theme as far as possible, but my entire MaterialApp uses the above theme (it’s a bit redacted). In it’s basic form, all I had to do to change to dark mode, was to add the following into my theme:

      brightness: Brightness.dark,

And that was it. I had a look through my app and quickly found three or so instances where my app wasn’t respecting my theme. Generally, I pull the colours from the theme, rather than it being hard-coded, for example:

Color backgroundcolor = Theme.of(context).dialogBackgroundColor;

The worst offender was my search delegate and after a bit of playing around, I ended up with what feels like a slight workaround, it now does what it did before if the brightness is light (which actually doesn’t respect my theme too much, but it works and doesn’t change anything) and then it fully respects my theme if the brightness is dark:

  @override
  ThemeData appBarTheme(BuildContext context) {
    final ThemeData theme = Theme.of(context);

    switch (theme.brightness) {
      case Brightness.dark:
        return theme;
        break;
      case Brightness.light:
        return theme.copyWith(
          primaryColor: Colors.white,
          primaryIconTheme: theme.primaryIconTheme.copyWith(color: Colors.grey),
          primaryColorBrightness: Brightness.light,
          primaryTextTheme: theme.textTheme,
        );
        break;
    }
  }

So that was it for being able to switch between dark mode and light mode in code, now to do it in run-time.

Switching during run-time

The implementation was quite straight-forward (I’m using the bloc pattern). Firstly, I hooked up a new setting in my application preferences (this doesn’t deserve a code example as it won’t be necessarily helpful for others), but what I end up with is a stream in my bloc which emits true or false depending on whether light or dark mode was selected. This is what the declaration in my bloc looks like to give you an idea (I start with false just to make sure that we have a value):

  BehaviorSubject<bool> _darkmodeController = BehaviorSubject<bool>(seedValue: false);
  Sink<bool> get inDarkMode => _darkmodeController.sink;
  Stream<bool> get outDarkMode => _darkmodeController.stream;

And then, the easiest part of all was hooking up the app (which I thought would be the most difficult) – btw I replaced irrelevant code with …:

class _BusPalState extends State<BusPal> with WidgetsBindingObserver {
  ...
  StreamSubscription themeListener;
  bool isDarkMode = false;

  @override
  void didChangeDependencies() {
    ...
    ApplicationPreferencesBloc _appPrefs =BlocProvider.of<ApplicationPreferencesBloc>(context);
    themeListener = _appPrefs.outDarkMode.listen((data) {
      setState(() {
        isDarkMode = data;
      });
    });

  @override
  void dispose() {
    ...
    themeListener.cancel();
    ...
  }

  @override
  Widget build(BuildContext context) {
  ThemeData theme = ThemeData(
      ...
      brightness: isDarkMode ? Brightness.dark :Brightness.light,
      ...
    );
    return MaterialApp(
      ...,
      theme: theme,
      ...
    );
}

And that is it. As I change from light to dark mode, Flutter takes care of the rest and even the transition looks really good.

I think I was worried as I don’t do too much setState, since I’m using bloc, but this just worked. It doesn’t break anything and it looks great.

This is why I love Flutter.

Here are some screenshots (in the interest of full disclosure, while I was looking some screens which would show light vs dark nicely, I found one other screen which doesn’t respect my theme – but it will be a quick and easy fix – test your apps properly!!).

Subscribe
Notify of
guest
1 Comment
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Nicolas
5 years ago

Search box with Dark Theme, I had the same issue, the text disappears. Your suggestion works fine. Cheers!