postSplashScreenTheme does not apply theme after splash screen
Asked Answered
O

4

6

After implementing the Splash Screen API as indicated by Android documentation (also this and this), the launch activity (which goes right after the splash screen) does not have dynamic color theming like the rest of the app. The splash screen <style> has the <item name="postSplashScreenTheme">@style/Theme.App</item> attribute which is supposed to apply the base application theme to the launch activity after the splash screen is cleared, but it doesn't. Everything else has been implemented like documentation dictates to a tee (activity class, manifest file, activity class, and themes.xml files).

I have tried all possible combinations, and the only one that "works" is when not setting the initial activity theme (or the whole activity) as the splash screen in the manifest (ie. android:theme="@style/Theme.App.Starting"). But then why would the documentation insist you do? What can I do to make it work as intended?

Edit: as requested, relevant code

Splash Theme:

    <!-- Splash Screen Theme. -->
    <style name="Theme.App.Starting" parent="Theme.SplashScreen">
        <item name="windowSplashScreenBackground">?android:attr/colorBackground</item>
        <item name="windowSplashScreenAnimatedIcon">@mipmap/ic_launcher_round</item>
        <item name="windowSplashScreenAnimationDuration">200</item>
        <item name="postSplashScreenTheme">@style/Theme.App</item>

        <!-- Status bar and Nav bar configs -->
        <item name="android:statusBarColor" tools:targetApi="l">?android:attr/colorBackground</item>
        <item name="android:navigationBarColor">?android:attr/colorBackground</item>
        <item name="android:windowLightStatusBar">true</item>
    </style>

manifest (only relevant attributes):

<application
        android:name=".application.App"
        android:theme="@style/Theme.App"
        tools:targetApi="31">

        <activity
            android:name=".ui.MainActivity"
            android:theme="@style/Theme.App.Starting">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

MainActivity:

  override fun onCreate(savedInstanceState: Bundle?) {

        setupSplashScreen()

        super.onCreate(savedInstanceState)
        /*...*/
    }

Application class:

class App : Application() {
    override fun onCreate() {
        super.onCreate()
        // Apply dynamic color
        DynamicColors.applyToActivitiesIfAvailable(this)
    }
}

Edit Jul 5, 2023: (possibly) final update

After a tremendous amount of testing and research, I have come to the conclusion that this is a bug and it cannot/will not be fixed anytime soon. I have also pin-pointed the reason for it.

The bug has been reported over a year and a half ago, and the reason it happens is that after the library calls postSplashScreenTheme, it sets the base theme of the app again which gets rid of the Material You (dynamic) colors. Another project encountered the same issue, which prevented them from implementing Material You for them. Someone suggested setting DynamicColors.applyToActivitiesIfAvailable(this) in each activity after the installSplashScreen(), but the status bar retained the base theme color instead of the dynamic color so it was useless. In my experiments, I found another workaround: not setting any splash theme in manifest (android:theme="@style/Theme.App.Starting") seems to work on api level 31+, but prevents the splash screen icon from showing at all in previous levels so it is also useless.

As of this update, Splash Screen API and Material You (dynamic color) conflict with each other and are therefore mutually exclusive. I will not be using dynamic colors since I need the functionality to load data at app start from splash screen api.

Overby answered 26/6, 2023 at 21:43 Comment(1)
Relevant theme, style and splash code, pls?Rotow
G
6

If you have enabled edge to edge displaying, the order of the lines should be as follows;

 override fun onCreate(savedInstanceState: Bundle?) {
    installSplashScreen()
    enableEdgeToEdge(
        navigationBarStyle = SystemBarStyle.dark(Color.TRANSPARENT),
        statusBarStyle = SystemBarStyle.dark(Color.TRANSPARENT)
    )
    super.onCreate(savedInstanceState)

I solved it this way

Gentille answered 7/5, 2024 at 21:35 Comment(0)
U
0

I don't know the details about these api, but I manually added setTheme to the application Activity to replace the corresponding theme after splashScreen ends.

 <style name="Theme.SmartCity" parent="android:Theme.Material.Light.NoActionBar">
        <item name="android:statusBarColor">@color/secondary</item>
    </style>
    <style name="Theme.Intro" parent="Theme.SplashScreen">
        <item name="android:windowActionBar">false</item>
        <item name="windowSplashScreenBackground">@color/tertiary</item>
        <item name="windowSplashScreenAnimatedIcon">@mipmap/app_logo</item>
        <item name="windowSplashScreenIconBackgroundColor">@color/secondary</item>
        <item name="windowSplashScreenAnimationDuration">1000</item>
        <item name="postSplashScreenTheme">@style/Theme.SmartCity</item>
    </style>
...
<activity
            android:name=".activity.IntroActivity"
            android:exported="true"
            android:theme="@style/Theme.Intro">
...
class IntroActivity : ComponentActivity() {


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setTheme(R.style.Theme_SmartCity)
        setContent {
...
Ushas answered 27/9, 2023 at 19:48 Comment(0)
S
0

I was having the same issue, as pointed in the docs you should use

fun Activity.installSplashScreen(): SplashScreen

within the onCreate() method before the call to super.onCreate() inside the Activity.

Check the docs out for further customization https://developer.android.com/reference/kotlin/androidx/core/splashscreen/SplashScreen#(android.app.Activity).installSplashScreen()

Sleepless answered 31/1, 2024 at 6:15 Comment(0)
A
0

Method installSplashScreen() becomes available with the companion object ...

import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
Administration answered 2/10, 2024 at 13:34 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.