6

Background

I know there is a new feature on Android Q to finally support dark theme (wrote here about detecting it).

I also know that there is "Night Light" feature (here) that makes the screen become more yellow-ish.

Supporting the theme choosing manually is something I've done for years (using simply setTheme on Activity's onCreate's first line of code), but I want to know if there is something automatic that will allow me to set it even before the app really starts, in the splash screen.

The problem

It seems a very old feature (since API 8!) has existed on Android for a very long time, of having "night" qualifier in the resources, and I never even tried it.

Sadly, because "dark theme" and night-related stuff are now more often talked about as the new features (here for example), I can't find what's the old one all about.

Looking at some articles and documentations, though, it seems it's almost completely manual:

What I've tried

I tried to set the various themes accordingly:

res/drawable/splash.xml

  <layer-list xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:opacity="opaque" tools:ignore="UnusedAttribute">
    <item android:gravity="fill">
      <shape android:shape="rectangle">
        <solid android:color="#fff"/>
      </shape>
    </item>
    ...
  </layer-list>

res/drawable-v29/splash.xml

<layer-list xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:opacity="opaque" tools:ignore="UnusedAttribute">
  <item android:gravity="fill">
    <shape android:shape="rectangle">
      <solid android:color="?attr/colorSurface"/>
    </shape>
  </item>
  ...
</layer-list>

res/drawable-night/splash.xml

<layer-list xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:opacity="opaque" tools:ignore="UnusedAttribute">
  <item android:gravity="fill">
    <shape android:shape="rectangle">
      <solid android:color="#000"/>
    </shape>
  </item>
  ...
</layer-list>

manifest

res/values/themes.xml

  <style name="AppTheme_splash" parent="@style/Theme.MaterialComponents.DayNight">
    <item name="android:windowBackground">@drawable/splash</item>
  </style>

res/values-v26/themes.xml

  <style name="AppTheme_splash" parent="@style/Theme.MaterialComponents.DayNight">
    <item name="android:windowSplashscreenContent">@drawable/splash</item>
  </style>

I tried to remove the android:windowBackground and android:windowSplashscreenContent, trying to see if it's automatic , but it didn't help.

The questions

Basically I just want to know about night-mode and if I can use it for the splash screen:

  1. When do the "night mode" that Android supports for so long kick in?

  2. Is it a os-global mode? Does the user control it?

  3. Is it automatic? Or completely manual by the current app?

  4. Does the mode stay later, even if I set it manually by the app and the app is killed ?

  5. Is it possible to set the theme of the application (meaning for the splash screen) to use this, so that while night-mode is enabled, it will use it to have a dark background?

  6. Is my code correct for this?

android developer
  • 114,585
  • 152
  • 739
  • 1,270
  • Yes the feature is supported but you need to use the new appCompat api so that your styles work properly.To set a specific mode you need to set it at start up every time so if the user changes the theme you should save the preference and restore it on startup. I suggest you set the the mode in Application.OnCreate() and remember this mode is not persisted you need persist the preference yourself. – Mihai Jun 29 '19 at 19:34
  • I forgot to mention that you can set it for individual activities as well. And it uses the old night resources qualifiers, they just tweaked the implementation in the new AppCompat to be easier to use. Also your splash theme will respect this mode. since you set it at application launch time. – Mihai Jun 29 '19 at 19:37
  • @Mihai Can you please show a working sample of it working on the splash screen? As far as I know, I can't use any code before it is shown, no? Also, as I wrote, it's not about Activities. For Activity, there are multiple solutions already. And why do you think it's related to appCompat? It was available since Android API 8... Please explain. What is night-mode exactly? Don't confuse it with Android Q's dark-theme, as I wrote... – android developer Jun 29 '19 at 21:12
  • Android Q uses the old night resources qualifiers. And in the new AppCompat they changed the implementation to be more consistent across api levels and easier to use by developers (it had an awkward implementation because it was made to be used by android auto). So in summary the old night resource qualifiers is being used to provide this "new" night mode. – Mihai Jun 29 '19 at 21:36
  • You can read more about it here https://developer.android.com/preview/features/darktheme and night mode is used by Android Q's dark-theme and it works down to 8 because those resource qualifiers where there, they where just being used to provide resourced for when the app was used in a car docked they had some callbacks trigger it for your app. But they changed that behaviour in the new appCompat so you can now easily tell the system what resources to use. And if you call in in Application.onCreate() that will also affect your splash screen. – Mihai Jun 29 '19 at 21:52
  • Can you please show it? I've tried multiple times and it didn't do anything. Please explain more and answer the questions in an answer, and not in comments. – android developer Jun 29 '19 at 22:49
  • I also have an application level setting of night mode vs day mode with AppCompat. Every bit of my app, including the actual LaunchActivity, properly follow the setting, but NOT the splash screen set via @drawable/launch_image. I cannot get that image to do anything other than use the day mode image. – StainlessSteelRat Mar 31 '20 at 19:52
  • 1
    @StainlessSteelRat Updated with an answer. Forgot about this question :) – android developer Mar 31 '20 at 20:38

1 Answers1

1

Actually it is possible to have a night modifier for splash screen.

Sadly, it happens right away, before any code can be used . So it's completely based on the settings of the OS, and not of the app itself.

Also, there is an annoying issue on the IDE, that for each Activity it will first use this theme that I've created for the splash.

Other than those 2 disadvantages, works fine, and you can see it for yourself on my app here.

Here:

res/drawable/splash.xml

<layer-list xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"
    android:opacity="opaque" tools:ignore="UnusedAttribute">
    <item android:gravity="fill">
        <shape android:shape="rectangle">
            <solid android:color="#fff" />
        </shape>
    </item>
    <item
        android:width="48dp" android:height="48dp" android:gravity="center">
        <bitmap
            android:gravity="center" android:src="@mipmap/ic_launcher_foreground" />
    </item>
</layer-list>

res/drawable-night/splash.xml

<layer-list xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"
    android:opacity="opaque" tools:ignore="UnusedAttribute">
    <item android:gravity="fill">
        <shape android:shape="rectangle">
            <solid android:color="#000" />
        </shape>
    </item>
    <item
        android:width="48dp" android:height="48dp" android:gravity="center">
        <bitmap
            android:gravity="center" android:src="@mipmap/ic_launcher_foreground" />
    </item>
</layer-list>

themes.xml

    <style name="AppTheme_splash" parent="@style/Theme.MaterialComponents.DayNight">
        <item name="android:windowBackground">@drawable/splash</item>
        <item name="android:navigationBarColor" tools:targetApi="lollipop">@android:color/transparent</item>
        <item name="android:statusBarColor" tools:targetApi="lollipop">?android:colorBackground</item>
        <item name="colorSecondary">?colorAccent</item>
        <item name="android:colorSecondary" tools:targetApi="n_mr1">?colorAccent</item>
    </style>

manifest

  <application android:theme="@style/AppTheme_splash" ...">
android developer
  • 114,585
  • 152
  • 739
  • 1,270