Splash / Loading
Arrancar la app pasa por dos pantallas de splash distintas, no una: el splash del sistema (obligatorio en Android 12+) y una pantalla de carga propia en Compose.
1. Splash del sistema (Theme.Act4RacingCards.Starting)
Sección titulada «1. Splash del sistema (Theme.Act4RacingCards.Starting)»<style name="Theme.Act4RacingCards.Starting" parent="Theme.SplashScreen"> <item name="windowSplashScreenBackground">@color/splash_background</item> <item name="postSplashScreenTheme">@style/Theme.Act4RacingCards</item></style>Se mantiene deliberadamente mínimo: sólo el color de fondo de marca + el ícono por defecto
de la app (sin windowSplashScreenAnimatedIcon personalizado). Es la pantalla que Android dibuja
él mismo entre el tap en el ícono y el primer frame de Compose — no se puede eliminar desde
Android 12 en adelante, así que se opta por no pelear contra ella.
class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { val splashScreen = installSplashScreen() super.onCreate(savedInstanceState) enableEdgeToEdge()
var appReady by mutableStateOf(false) splashScreen.setKeepOnScreenCondition { !appReady } // ... }}2. LoadingScreen (Compose)
Sección titulada «2. LoadingScreen (Compose)»En cuanto Compose puede dibujar su primer frame, appReady = true libera el splash del sistema
y aparece LoadingScreen: el wordmark “RACING CARDS” centrado sobre el mismo color de fondo,
durante LOADING_MILLIS = 1100L.
private const val LOADING_MILLIS = 1100L
setContent { Act4RacingCardsTheme { var showLoader by remember { mutableStateOf(true) } LaunchedEffect(Unit) { appReady = true // entrega el control del splash del sistema delay(LOADING_MILLIS) showLoader = false } if (showLoader) LoadingScreen() else RacingCardsApp() }}@Composablefun LoadingScreen(modifier: Modifier = Modifier) { Box( modifier = modifier.fillMaxSize().background(colorResource(R.color.splash_background)), contentAlignment = Alignment.Center, ) { Image( painter = painterResource(R.drawable.splash_wordmark), contentDescription = "Racing Cards", contentScale = ContentScale.Fit, modifier = Modifier.fillMaxWidth(0.72f), ) }}Un solo color controla ambas pantallas
Sección titulada «Un solo color controla ambas pantallas»R.color.splash_background (#01090D) es la única fuente de verdad para el color de fondo
tanto del splash del sistema como de LoadingScreen — cambiar ese único recurso recolorea las
dos pantallas a la vez, evitando que se desincronicen visualmente.
Secuencia de arranque
sequenceDiagram
participant OS as Android (SplashScreen API)
participant MA as MainActivity
participant LS as LoadingScreen (Compose)
participant App as RacingCardsApp
OS->>MA: tap en el ícono
OS->>OS: dibuja splash nativo (ic_launcher sobre #01090D)
MA->>MA: installSplashScreen() + setKeepOnScreenCondition
MA->>MA: setContent { ... }
MA->>OS: appReady = true
OS->>LS: libera el splash nativo, entra LoadingScreen
LS->>LS: muestra splash_wordmark sobre #01090D (1100ms)
LS->>App: showLoader = false
App-->>MA: Gallery visible

