Status Update
Comments
de...@gmail.com <de...@gmail.com> #2
Hey hughesno1@, when do you add the onPreDrawListener to delay the rendering of activity? Mind providing us with a sample application?
wi...@google.com <wi...@google.com> #3
wi...@google.com <wi...@google.com> #4
de...@gmail.com <de...@gmail.com> #5
wi...@google.com <wi...@google.com> #6
Could you try to use UiModeManager#setApplicationNightMode(int) once you detect
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S)
This API should only effect your application instead of entire device.
Once its called, the config can be persist in system. So next time when user cold launch the app, system can read and pre-set the config when fork the process.
The splash screen window shall be created based on the theme regarding to this configuration.
de...@gmail.com <de...@gmail.com> #7
```
val prefModeIsNight = sharedPref.prefBoolean(DARK_THEME)
// This will be the top level handling of theme
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
uiModeManager.setApplicationNightMode(
when (prefModeIsNight) {
true -> UiModeManager.MODE_NIGHT_YES
else -> UiModeManager.MODE_NIGHT_NO
}
)
}
else {
AppCompatDelegate.setDefaultNightMode(
when (prefModeIsNight) {
true -> AppCompatDelegate.MODE_NIGHT_YES
else -> AppCompatDelegate.MODE_NIGHT_NO
}
)
}
```
de...@gmail.com <de...@gmail.com> #8
Hello, I noticed that in Android 10 and 11 the Splash Screen API is using the device theme first before AppCompatDelegate
. Meaning if you want your app to have its own config settings for Day/Night mode with API like SharedPreferences
, then the time your app begins in hot start the Splash API will first used the device Dark Theme settings which I assumed is based on UiModeManager.setNightMode
then quickly changed to using AppCompatDelegate
. This behavior does not exist in Android 12 and above since the introduction of UiModeManager.setApplicationNightMode
which handles everything from the beginning. Any workaround for this? It can be a bad user experience imagining the user will first get a Day Mode Splash then suddenly changed to Night Mode. Thanks.
wi...@google.com <wi...@google.com> #9
Re #8,
Hi there,
I think a while but seems the splash screen support library cannot fullfil this requirement for devices with Android 11 and below, since this will eventually needs the support from Android framework. However, there is no similar API like UiModeManager.setApplicationNightMode in the earlier version. Sounds like we can only use the tranditional way to draw an app made splash screen activity, so it can be changed at runtime, but still, not smooth like what we can do on Android 12.
de...@gmail.com <de...@gmail.com> #10
ag...@physics.msu.ru <ag...@physics.msu.ru> #11
wi...@google.com <wi...@google.com>
de...@gmail.com <de...@gmail.com> #12
Hey, did you fix this case in your app? "It can be a bad user experience imagining the user will first get a Day Mode Splash then suddenly changed to Night Mode." I've read the discussion above, but didn't completely understand it. If you have a dark mode toggle inside the app and its state is saved, for example, in a Room DB, is it possible to get and apply the right theme for system splash screen on Android 12+, so that splash screen corresponds correctly to dark mode toggle state and not to device theme? For devices with android < 12 there is a custom splash screen, and for android 12+
android:windowSplashScreenBackground
and similar resources are used. Also right now in a case when app and device themes differ sometimes after showing system splash screen app shows some background and nothing more. So I wonder are these things connected to each other or not?
// This will be the top level handling of theme
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
uiModeManager.setApplicationNightMode(
when (isAppNight) {
DAY_THEME -> UiModeManager.MODE_NIGHT_NO // User set this explicitly
NIGHT_THEME -> UiModeManager.MODE_NIGHT_YES // User set this explicitly
else -> UiModeManager.MODE_NIGHT_AUTO // Follow the device Dark Theme settings when not define yet by user
}
)
} else {
AppCompatDelegate.setDefaultNightMode(
when (isAppNight) {
DAY_THEME -> AppCompatDelegate.MODE_NIGHT_NO // User set this explicitly
NIGHT_THEME -> AppCompatDelegate.MODE_NIGHT_YES // User set this explicitly
else -> AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM // For Android 10 and 11, follow the device Dark Theme settings when not define yet by user
}
)
}
The above code should let you specify your app's theme for splash screen. However not smooth in Android 10, 11 and below except 5 where if you decide to manage your own day and night theme example using SharedPreferences
instead of following the device day and dark theme, your splash screen theme will use the device day and dark theme first then transition to your app's configuration which I think is not a good experience.
de...@gmail.com <de...@gmail.com> #13
de...@gmail.com <de...@gmail.com> #14
Re #11,
I recently decided that if the app is Android 9 P - API (28) and below, I will handle app theme using AppCompatDelegate.setDefaultNightMode
and SharedPreferences
combine. Above that starting Android 10 Q - API (29), I will just follow the device Dark Theme. It has pros and cons.
Pros:
- We are now aligned with the user preferred system-wide theme.
- It fixed (more like a workaround) the issue on Android 10 and 11 where the Splash Screen will first use the device Dark Theme then quickly changed to
AppCompatDelegate.setDefaultNightMode
.
Cons:
- We can no longer separate our app theme from the system level. If the user wants to change our app theme, then it will be a system-wide thru Dark Theme at settings in which other app may not support well.
Application class
val isAppNight = userPreferences.prefInt(DAY_NIGHT_THEME)
// To avoid the inconsistency of Splash Screen API on some older Android version
// we will follow the device Dark Theme settings starting Android 10 (Q) and above
// Reference: https://issuetracker.google.com/issues/240533989#comment8
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P) {
// AppCompatDelegate.setDefaultNightMode is non-persistent so we use it along with SharedPreferences
AppCompatDelegate.setDefaultNightMode(
when (isAppNight) {
AppCompatDelegate.MODE_NIGHT_NO -> AppCompatDelegate.MODE_NIGHT_NO // User set this explicitly
AppCompatDelegate.MODE_NIGHT_YES -> AppCompatDelegate.MODE_NIGHT_YES // User set this explicitly
else -> AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
}
) // Apply appropriate theme before launching any Activity
}
Activity or Fragment class
// To avoid the inconsistency of Splash Screen API on some older Android version
// we will follow the device Dark Theme settings starting Android 10 (Q) and above
// Reference: https://issuetracker.google.com/issues/240533989#comment8
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
val intent = Intent(Settings.ACTION_DISPLAY_SETTINGS)
openInWebView(intent)
}
else {
item.isChecked = !item.isChecked
val theme = when (item.isChecked) {
true -> AppCompatDelegate.MODE_NIGHT_YES
else -> AppCompatDelegate.MODE_NIGHT_NO
}
AppCompatDelegate.setDefaultNightMode(theme)
// Save settings configuration in SharedPreferences
userPreferences.prefInt(DAY_NIGHT_THEME, theme)
}
Description
Version used: 1.0.0-rc01
Devices/Android versions reproduced on: Android L and T
If this is a bug in the library, we would appreciate if you could attach:
Attributes like `windowSplashScreenBackground`, `windowSplashScreenAnimatedIcon`, and `windowSplashScreenIconBackgroundColor` does not respect day and night theme specially.
There is an existing report here in SO.