Fork us on GitHub

Dark Mode

Initial support for dark mode detection
Dark Mode

Dark Mode

We recently added support to detect whether a device is running in dark/light mode based on this issue. Some of the code in the implementation is also derived from that issue submitted by Javier.

Detecting Dark Mode

Dark mode can be detected using APIs in the CN and Display classes. Specifically isDarkMode() and setDarkMode(Boolean).

Notice that isDarkMode() returns Boolean and not boolean. This means that null is a valid value for this method. The case of null indicates that dark mode detection isn’t available or isn’t working on this platform.

You can override the dark mode setting for the platform using setDarkMode().

At this time dark mode detection only works on iOS, Android and JavaScript. We tried adding desktop support for that, but it proved a bit challenging. UWP detection isn’t supported at the moment.

We don’t currently have an event based API for dark mode detection. While nice, this isn’t universally supported and can be circumvented with a simple timer.

Native/Builtin Theme Support

Ideally, the app would just switch to dark mode seamlessly but right now this isn’t the case. The theme constant darkModeBool changes some deep core theme styles to match dark mode if isDarkMode() is true. In the future it might trigger a dark version of the native theme. At the moment we don’t have dark versions of the themes.

To create a dark version of your app create a new resource file for dark mode and load it conditionally based on dark mode. You can do the same for CSS by creating a CSS file called dark.css and editing your build.xml file to replicate the CSS conversion line. Specifically:

<target name="-cn1-compile-css" if="codename1.cssTheme">
    <java jar="${user.home}/.codenameone/designer_1.jar" fork="true" failonerror="true">
        <jvmarg value="-Dcli=true"/>
        <arg value="-css"/>
        <arg file="css/theme.css"/>
        <arg file="src/theme.res"/>
    </java>
    <java jar="${user.home}/.codenameone/designer_1.jar" fork="true" failonerror="true">
        <jvmarg value="-Dcli=true"/>
        <arg value="-css"/>
        <arg file="css/dark-theme.css"/>
        <arg file="src/dark-theme.res"/>
    </java>
</target>

Then in Java code you can load a different theme and change themes at runtime using our builtin theming.

You can put two themes in a single resource file but since most settings can’t be reused between dark/light the benefit is limited

You can load a new resource file theme by using:

theme = UIManager.initFirstTheme("/resource");

You can then apply the theme to the current form dynamically using refreshTheme() on the form.

Moving Forward

We hope to add additional dark/light templates and also port the native themes to include dark counterparts. This work isn’t scheduled yet but this is the direction.

Share this Post:

Posted by Shai Almog

Shai is the co-founder of Codename One. He's been a professional programmer for over 25 years. During that time he has worked with dozens of companies including Sun Microsystems.
For more follow Shai on Twitter & github.