androidandroid-studioandroid-jetpack-composeandroid-studio-bumblebeeandroid-jetpack-compose-preview

Jetpack Compose Previews: No Backgrounds, No System UI


I am bootstrapping a new app with Jetpack Compose and Material 3. I've created a bunch of new apps lately with this configuration, so this problem has me stuck: I cannot get the IDE's compose previews to show a background or system UI. The compiled app works great.

I tried building this sample app with Jetpack Compose + Material 3 I created a while back and all of the previews are just fine in the same version of the IDE. I also tried downgrading my libraries to match that sample app's libraries. No luck. The sample app has working previews, mine does not.

I DO have the compose UI tooling included in my Gradle script for my debug variant, and I am previewing with the debug variant.

Thoughts?

Here is what I see:

IDE preview

This is how I generate this screen code sample:

@Composable
fun LoadingScreen() {
    Column {
        Text("Example")
    }
}

@Preview(name = "Light Mode", showBackground = true)
@Preview(name = "Dark Mode", uiMode = Configuration.UI_MODE_NIGHT_YES, showBackground = true)
@Preview(name = "Full Preview", showSystemUi = true)
@Composable
fun PreviewLoadingScreen() {
    MyTheme {
        LoadingScreen()
    }
}

My theme is pretty stock for Material 3:

private val DarkColorScheme = darkColorScheme(
    // ...
)

private val LightColorScheme = lightColorScheme(
    // ...
)

@Composable
fun MyTheme(
    darkTheme: Boolean = isSystemInDarkTheme(),
    dynamicColor: Boolean = true,
    content: @Composable () -> Unit
) {
    val colorScheme = when {
        dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
            val context = LocalContext.current
            if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)
        }
        darkTheme -> DarkColorScheme
        else -> LightColorScheme
    }
    val view = LocalView.current
    if (!view.isInEditMode) {
        SideEffect {
            (view.context as Activity).window.statusBarColor = colorScheme.primary.toArgb()
            ViewCompat.getWindowInsetsController(view)?.isAppearanceLightStatusBars = darkTheme
        }
    }

    MaterialTheme(
        colorScheme = colorScheme,
        typography = Typography,
        content = content
    )
}

Here is what I am using:

  • Android Studio Bumblebee: 2021.1.1 Patch 1
  • AGP: 7.2.0-alpha05
  • Jetpack Compose: 1.2.0-alpha03 (also tried 1.1.0)
  • Gradle: 7.4
  • Kotlin: 1.6.10
  • androidx.compose.material3:material3:1.0.0-alpha05
  • com.google.android.material:material:1.6.0-alpha01

Solution

  • I found out two things that were giving me headaches and broke the view:

    1. My app was broken up into two modules, the main app module, and a shared module. The shared module had both the Material com.google.android.material:material:1.6.0-alpha01 and Material 3 androidx.compose.material3:material3:1.0.0-alpha05 libraries in the implementation() list in Gradle. However, my app module only had the Material 3 library. Including the Material library in addition in the app module fixed this issue.
    2. Throughout this process, I learned that it is essential to have your app's theme inherit from one of the Theme.Material3.* base themes, and also to apply your theme to the <application /> tag in your manifest. Android Studio will try to warn you that your android:theme on your <application /> tag can be removed since it only needs to go onto an <activity />, but that advice is incorrect. Include your theme in both places.