Android Edge-to-Edge & SplashScreen API — Modern App Launch Guide
Building modern Android apps means embracing edge-to-edge displays and smooth launch experiences. This guide covers the essential APIs that make it happen.
Edge-to-Edge Display Fundamentals
Edge-to-edge UI means your app content extends behind the system bars (status bar, navigation bar, IME). This creates an immersive experience but requires careful handling.
Step 1: Enable Edge-to-Edge
Start by calling enableEdgeToEdge() in your Activity:
import androidx.activity.enableEdgeToEdge
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContent {
MyApp()
}
}
}
This single call sets up safe insets handling across your entire app.
Handling WindowInsets
System bars take up screen real estate. You need to know their dimensions to avoid drawing under them.
statusBars & navigationBars Insets
Use WindowInsets to get bar dimensions:
import androidx.compose.foundation.layout.*
Box(
modifier = Modifier
.fillMaxSize()
.systemBarsPadding() // Adds padding for all system bars
) {
Text("Safe content area")
}
For granular control:
val insets = WindowInsets.systemBars
val topPadding = insets.getTop(LocalDensity.current)
val bottomPadding = insets.getBottom(LocalDensity.current)
IME Padding (Keyboard Safe)
When the IME (input method editor / keyboard) appears, adjust padding to keep content visible:
Box(
modifier = Modifier
.fillMaxSize()
.imePadding() // Automatically adjusts when keyboard shows/hides
) {
TextField(
value = text,
onValueChange = { text = it },
modifier = Modifier.fillMaxWidth()
)
}
Scaffold Auto-Handling
Scaffold in Jetpack Compose automatically manages insets for you:
Scaffold(
topBar = {
TopAppBar(
title = { Text("My App") },
modifier = Modifier.statusBarsPadding() // Status bar safe
)
},
bottomBar = {
BottomAppBar(
modifier = Modifier.navigationBarsPadding() // Nav bar safe
) {
// Bottom navigation
}
}
) { innerPadding ->
Box(
modifier = Modifier
.fillMaxSize()
.padding(innerPadding) // Respects all insets
) {
// Your content
}
}
Smooth App Launch with SplashScreen API
The SplashScreen API provides a polished launch experience with Android 12+ style animated splash screens.
Installation
Add the dependency to your build.gradle.kts:
dependencies {
implementation("androidx.core:core-splashscreen:1.0.1")
}
Basic Setup
In your launcher Activity, before setContent():
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Install splash screen BEFORE setContent
val splashScreen = installSplashScreen()
enableEdgeToEdge()
setContent {
MyApp()
}
}
}
Keep Splash Visible During Loading
Use setKeepOnScreenCondition to control when the splash screen exits:
class MainActivity : ComponentActivity() {
private val viewModel: MainViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val splashScreen = installSplashScreen()
// Keep splash visible while loading
splashScreen.setKeepOnScreenCondition {
viewModel.isLoading.value
}
enableEdgeToEdge()
setContent {
MyApp()
}
}
}
The splash screen automatically exits when setKeepOnScreenCondition returns false.
Customize Exit Animation
Add a custom exit animation:
splashScreen.setOnExitAnimationListener { splashScreenView ->
val slideOut = ObjectAnimator.ofFloat(
splashScreenView,
View.TRANSLATION_Y,
0f,
-splashScreenView.height.toFloat()
)
slideOut.duration = 500
slideOut.doOnEnd {
splashScreenView.remove()
}
slideOut.start()
}
Configure Branding via Theme
Customize the splash screen appearance in your app theme (res/values/themes.xml):
<style name="Theme.MyApp" parent="Theme.MaterialComponents.DayNight">
<!-- Splash screen brand image (must be 108dp) -->
<item name="windowSplashScreenAnimatedIcon">@drawable/ic_splash_brand</item>
<!-- Brand icon background color -->
<item name="windowSplashScreenBrandingImage">@drawable/ic_branding</item>
<!-- Animated icon animation -->
<item name="windowSplashScreenAnimationDuration">1000</item>
<!-- Background color -->
<item name="android:windowBackground">@color/splash_background</item>
</style>
Best Practices
Keep splash screens short: Don't use them for actual loading. Pre-load critical data before app launch if possible.
Test insets on multiple devices: Screen sizes vary. Test on tablets, foldables, and phones with different notch/cutout designs.
Use Material 3 colors: The splash screen automatically respects your Material 3 color scheme.
Combine edge-to-edge with windowInsets: Don't forget to add padding/margin to your actual content—edge-to-edge is just the container.
Monitor keyboard state: Use
imePadding()to adjust layouts when the IME appears.
Quick Reference
// Enable edge-to-edge
enableEdgeToEdge()
// Add safe area padding (easy way)
Box(modifier = Modifier.systemBarsPadding())
// Handle keyboard
TextField(modifier = Modifier.imePadding())
// Install splash screen
val splashScreen = installSplashScreen()
splashScreen.setKeepOnScreenCondition { isLoading }
splashScreen.setOnExitAnimationListener { /* custom animation */ }
// Use Scaffold (automatic insets)
Scaffold(
topBar = { /* status bar safe */ },
bottomBar = { /* nav bar safe */ }
)
Next Steps
- Read the official SplashScreen API docs
- Explore WindowInsets documentation
- Check edge-to-edge design guide
Ready to build production-grade Android apps? Grab 8 Android App Templates with complete edge-to-edge + Material 3 setup: 8 Android App Templates → https://myougatheax.gumroad.com
Master the fundamentals, ship apps faster. 🚀
Top comments (0)