Schermate iniziali

A partire da Android 12, l'API SplashScreen consente di avviare le app con animazioni, che includono un movimento in-app al momento del lancio, una schermata iniziale che mostra l'icona dell'app e una transizione all'app stessa. Un SplashScreen è un Window e pertanto copre un Activity.

Figura 1. Una schermata iniziale.

L'esperienza della schermata iniziale aggiunge elementi di design standard a ogni lancio dell'app, ma è anche personalizzabile, in modo che l'app mantenga il proprio branding unico.

Oltre a utilizzare l'API della piattaforma SplashScreen, puoi anche utilizzare la libreria compatibile SplashScreen, che aggrega l'API SplashScreen.

Come funziona la schermata iniziale

Quando un utente avvia un'app mentre il processo dell'app non è in esecuzione (avvio a freddo) o Activity non viene creato (avvio a caldo), si verificano i seguenti eventi:

  1. Il sistema mostra la schermata iniziale utilizzando i temi e le animazioni che definisci.

  2. Quando l'app è pronta, la schermata iniziale viene chiusa e l'app viene visualizzata.

La schermata iniziale non viene mai visualizzata durante un avvio rapido.

Elementi e meccanismi della schermata iniziale

Gli elementi della schermata iniziale sono definiti dai file di risorse XML nel file manifest Android. Esistono versioni delle modalità Luce e Buio per ogni elemento.

Gli elementi personalizzabili di una schermata iniziale sono costituiti dall'icona dell'app, dallo sfondo dell'icona e dallo sfondo della finestra:

Un'immagine che mostra gli elementi contenuti in una schermata iniziale
Figura 2. Elementi personalizzabili di una schermata iniziale.

Considera i seguenti elementi, mostrati nella Figura 2:

1 L'icona dell'app deve essere disegnabile vettoriale. Può essere statico o animato. Sebbene le animazioni possano avere una durata illimitata, consigliamo di non superare i 1000 millisecondi. L'icona in Avvio applicazioni è l'icona predefinita.

2 Lo sfondo dell'icona è facoltativo e utile se hai bisogno di un maggiore contrasto tra l'icona e lo sfondo della finestra. Se utilizzi un'icona adattiva, il suo sfondo viene visualizzato se il contrasto con lo sfondo della finestra è sufficiente.

3 Come per le icone adattive, un terzo del primo piano è mascherato.

4 Lo sfondo della finestra è costituito da un solo colore opaco. Se lo sfondo della finestra è impostato ed è di un colore a tinta unita, viene utilizzato per impostazione predefinita se l'attributo non è impostato.

Dimensioni schermata iniziale

L'icona della schermata iniziale utilizza le stesse specifiche delle icone adattive, come descritto di seguito:

  • Immagine con brand: le dimensioni devono essere 200 × 80 dp.
  • Icona dell'app con un'icona sullo sfondo: deve avere dimensioni di 240 × 240 dp e rientrare in un cerchio di 160 dp di diametro.
  • Icona dell'app senza sfondo icona: deve avere dimensioni di 288 × 288 dp e rientrare in un cerchio di 192 dp di diametro.

Ad esempio, se la dimensione originale di un'immagine è 300 × 300 dp, l'icona deve rientrare in un cerchio con un diametro di 200 dp. Tutto ciò che è al di fuori del cerchio diventa invisibile (mascherato).

Un'immagine che mostra icone di dimensioni diverse per uno sfondo in tinta unita e trasparente
Figura 3. Dimensioni dell'icona della schermata iniziale per sfondi in tinta unita e trasparenti.

Animazioni della schermata iniziale e sequenza di avvio

Una latenza aggiuntiva è spesso associata all'avvio di un'app con un avvio a freddo. L'aggiunta di un'icona animata alla schermata iniziale ha un evidente fascino estetico e offre un'esperienza più premium. Da una ricerca sugli utenti risulta che il tempo di avvio percepito è inferiore quando si visualizza un'animazione.

Un'animazione della schermata iniziale è incorporata nei componenti della sequenza di avvio, come mostrato nella Figura 4.

Un'immagine che mostra la sequenza di avvio in dodici frame consecutivi, a partire dal tocco dell'icona di avvio, che riempie lo schermo mentre si ingrandisce
Figura 4. Avvia sequenza.
  1. Inserisci l'animazione: dalla visualizzazione del sistema alla schermata iniziale. È controllato dal sistema e non è personalizzabile.

  2. Schermata iniziale (visualizzata durante la parte di attesa della sequenza): puoi personalizzare la schermata iniziale in modo da creare l'animazione e il branding del tuo logo. Per funzionare correttamente, deve soddisfare i requisiti descritti in questa pagina.

  3. Esci dall'animazione: consiste nell'animazione che nasconde la schermata iniziale. Se vuoi personalizzarla, utilizza SplashScreenView e la relativa icona. Su questi elementi puoi eseguire qualsiasi animazione, con impostazioni di trasformazione, opacità e colore. In questo caso, rimuovi manualmente la schermata iniziale al termine dell'animazione.

Durante l'esecuzione dell'animazione dell'icona, l'avvio dell'app ti offre la possibilità di saltare la sequenza nei casi in cui l'app è pronta in precedenza. L'app attiva onResume() o il timeout della schermata iniziale si interrompe automaticamente, quindi assicurati che il movimento possa essere ignorato comodamente. La schermata iniziale deve essere chiusa con onResume() solo quando l'app è stabile dal punto di vista visivo, senza che siano necessari ulteriori rotellini. L'introduzione di un'interfaccia incompleta può essere fastidiosa per gli utenti e dare un'impressione di imprevedibilità o di smalto.

Requisiti per l'animazione della schermata iniziale

La schermata iniziale deve rispettare le seguenti specifiche:

  • Imposta il colore di sfondo di una singola finestra senza trasparenza. Le modalità Giorno e Notte sono supportate con la libreria compatibile di SplashScreen.

  • Assicurati che l'icona animata soddisfi le seguenti specifiche:

    • Formato: l'icona deve essere un file XML AnimatedVectorDrawable (AVD).
    • Dimensioni. Le dimensioni di un'icona di visualizzazione di pagina devono essere quattro volte superiori a quelle di un'icona adattiva, come segue:
      • L'area dell'icona deve essere di 432 dp, ovvero quattro volte l'area di 108 dp di un'icona adattiva non mascherata.
      • I due terzi interni dell'immagine sono visibili sull'icona in Avvio applicazioni e devono avere una dimensione di 288 dp, ovvero quattro volte i 72 dp che formano l'area mascherata interna di un'icona adattiva.
    • Durata: consigliamo di non superare i 1000 ms sugli smartphone. Puoi utilizzare un avvio ritardato, che però non può superare i 166 ms. Se il tempo di avvio dell'app è superiore a 1000 ms, valuta la possibilità di utilizzare un'animazione in loop.
  • Stabilisci un momento appropriato per chiudere la schermata iniziale, che si verifica quando l'app inizia a usare il primo frame. Puoi personalizzare ulteriormente questa impostazione come descritto nella sezione relativa a come mantenere la schermata iniziale sullo schermo per periodi più lunghi.

Risorse della schermata iniziale

Figura 5. Esempio di durata di visualizzazione media.

Scarica lo starter kit di esempio, che spiega come creare, formattare ed esportare un'animazione in una visualizzazione di visualizzazione media. Comprende quanto segue:

  • Il file di progetto Adobe After Effects dell'animazione.
  • File XML AVD finale esportato.
  • GIF di esempio dell'animazione.

Scaricando questi file, accetti i Termini di servizio di Google.

Le Norme sulla privacy di Google descrivono il modo in cui vengono gestiti i dati in questo servizio.

Personalizza la schermata iniziale nell'app

Per impostazione predefinita, SplashScreen utilizza la windowBackground del tuo tema se windowBackground è di un solo colore. Per personalizzare la schermata iniziale, aggiungi attributi al tema dell'app.

Puoi personalizzare la schermata iniziale della tua app in uno dei seguenti modi:

  • Imposta gli attributi del tema per modificarne l'aspetto.

  • Tienilo sullo schermo per un periodo più lungo.

  • Personalizza l'animazione per chiudere la schermata iniziale.

Inizia

La libreria SplashScreen principale mette a disposizione la schermata iniziale di Android 12 su tutti i dispositivi dall'API 23. Per aggiungerlo al tuo progetto, aggiungi il seguente snippet al file build.gradle:

Alla moda

dependencies {
    implementation "androidx.core:core-splashscreen:1.0.0"
}

Kotlin

dependencies {
    implementation("androidx.core:core-splashscreen:1.0.0")
}

Imposta un tema per la schermata iniziale di cui modificare l'aspetto

Puoi specificare i seguenti attributi nel tema Activity per personalizzare la schermata iniziale della tua app. Se hai già un'implementazione precedente della schermata iniziale che utilizza attributi quali android:windowBackground, valuta la possibilità di fornire un file di risorse alternativo per Android 12 e versioni successive.

  1. Utilizza windowSplashScreenBackground per riempire lo sfondo con un singolo colore specifico:

    <item name="android:windowSplashScreenBackground">@color/...</item>
    
  2. Utilizza windowSplashScreenAnimatedIcon per sostituire l'icona al centro della finestra iniziale.

    Per le app che hanno come target solo Android 12 (livello API 32), procedi nel seguente modo:

    Se l'oggetto è animabile e disegnabile tramite AnimationDrawable e AnimatedVectorDrawable, imposta windowSplashScreenAnimationDuration per riprodurre l'animazione mentre mostri la finestra iniziale. Questa operazione non è necessaria per Android 13, perché la durata viene dedotta direttamente dal AnimatedVectorDrawable.

    <item name="android:windowSplashScreenAnimatedIcon">@drawable/...</item>
    
  3. Utilizza windowSplashScreenAnimationDuration per indicare la durata dell'animazione dell'icona della schermata iniziale. L'impostazione non ha alcun effetto sul momento effettivo durante il quale viene visualizzata la schermata iniziale, ma puoi recuperarla quando personalizzi l'animazione di uscita dalla schermata iniziale utilizzando SplashScreenView.getIconAnimationDuration. Per maggiori dettagli, consulta la sezione seguente su come mantenere la schermata iniziale sullo schermo per periodi più lunghi.

    <item name="android:windowSplashScreenAnimationDuration">1000</item>
    
  4. Utilizza windowSplashScreenIconBackgroundColor per impostare uno sfondo dietro l'icona della schermata iniziale. Questa opzione è utile se il contrasto tra lo sfondo della finestra e l'icona non è sufficiente.

    <item name="android:windowSplashScreenIconBackgroundColor">@color/...</item>
    
  5. Puoi utilizzare windowSplashScreenBrandingImage per impostare un'immagine da mostrare nella parte inferiore della schermata iniziale. Tuttavia, le linee guida sulla progettazione sconsigliano l'utilizzo di un'immagine di branding.

    <item name="android:windowSplashScreenBrandingImage">@drawable/...</item>
    
  6. Puoi utilizzare windowSplashScreenBehavior per specificare se la tua app deve sempre mostrare l'icona nella schermata iniziale in Android 13 e versioni successive. Il valore predefinito è 0 e mostra l'icona sulla schermata iniziale se l'attività di avvio imposta splashScreenStyle su SPLASH_SCREEN_STYLE_ICON oppure segue il comportamento del sistema se l'attività di avvio non specifica uno stile. Se preferisci non visualizzare mai una schermata iniziale vuota e vuoi sempre che venga visualizzata l'icona animata, imposta il valore icon_preferred.

    <item name="android:windowSplashScreenBehavior">icon_preferred</item>
    

Mantieni la schermata iniziale sullo schermo per periodi più lunghi

La schermata iniziale viene ignorata non appena l'app apre il primo frame. Se devi caricare una piccola quantità di dati, ad esempio caricare le impostazioni in-app da un disco locale in modo asincrono, puoi utilizzare ViewTreeObserver.OnPreDrawListener per sospendere l'app e disegnare il primo frame.

Se l'attività iniziale termina prima di disegnare (ad esempio, non impostando la visualizzazione del contenuto e la terminazione prima del giorno onResume), l'ascolto di pre-disposizione non è necessario.

Kotlin

// Create a new event for the activity.
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    // Set the layout for the content view.
    setContentView(R.layout.main_activity)

    // Set up an OnPreDrawListener to the root view.
    val content: View = findViewById(android.R.id.content)
    content.viewTreeObserver.addOnPreDrawListener(
        object : ViewTreeObserver.OnPreDrawListener {
            override fun onPreDraw(): Boolean {
                // Check whether the initial data is ready.
                return if (viewModel.isReady) {
                    // The content is ready. Start drawing.
                    content.viewTreeObserver.removeOnPreDrawListener(this)
                    true
                } else {
                    // The content isn't ready. Suspend.
                    false
                }
            }
        }
    )
}

Java

// Create a new event for the activity.
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // Set the layout for the content view.
    setContentView(R.layout.main_activity);

    // Set up an OnPreDrawListener to the root view.
    final View content = findViewById(android.R.id.content);
    content.getViewTreeObserver().addOnPreDrawListener(
            new ViewTreeObserver.OnPreDrawListener() {
                @Override
                public boolean onPreDraw() {
                    // Check whether the initial data is ready.
                    if (mViewModel.isReady()) {
                        // The content is ready. Start drawing.
                        content.getViewTreeObserver().removeOnPreDrawListener(this);
                        return true;
                    } else {
                        // The content isn't ready. Suspend.
                        return false;
                    }
                }
            });
}

Personalizza l'animazione per chiudere la schermata iniziale

Puoi personalizzare ulteriormente l'animazione della schermata iniziale tramite Activity.getSplashScreen().

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    // ...

    // Add a callback that's called when the splash screen is animating to the
    // app content.
    splashScreen.setOnExitAnimationListener { splashScreenView ->
        // Create your custom animation.
        val slideUp = ObjectAnimator.ofFloat(
            splashScreenView,
            View.TRANSLATION_Y,
            0f,
            -splashScreenView.height.toFloat()
        )
        slideUp.interpolator = AnticipateInterpolator()
        slideUp.duration = 200L

        // Call SplashScreenView.remove at the end of your custom animation.
        slideUp.doOnEnd { splashScreenView.remove() }

        // Run your animation.
        slideUp.start()
    }
}

Java

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // ...

    // Add a callback that's called when the splash screen is animating to the
    // app content.
    getSplashScreen().setOnExitAnimationListener(splashScreenView -> {
        final ObjectAnimator slideUp = ObjectAnimator.ofFloat(
                splashScreenView,
                View.TRANSLATION_Y,
                0f,
                -splashScreenView.getHeight()
        );
        slideUp.setInterpolator(new AnticipateInterpolator());
        slideUp.setDuration(200L);

        // Call SplashScreenView.remove at the end of your custom animation.
        slideUp.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                splashScreenView.remove();
            }
        });

        // Run your animation.
        slideUp.start();
    });
}

All'inizio di questo callback, viene avviato il drawable vettoriale animato nella schermata iniziale. A seconda della durata dell'avvio dell'app, l'elemento drawable potrebbe trovarsi nel mezzo dell'animazione. Utilizza SplashScreenView.getIconAnimationStart per sapere quando è stata avviata l'animazione. Puoi calcolare la durata rimanente dell'animazione dell'icona come segue:

Kotlin

// Get the duration of the animated vector drawable.
val animationDuration = splashScreenView.iconAnimationDuration
// Get the start time of the animation.
val animationStart = splashScreenView.iconAnimationStart
// Calculate the remaining duration of the animation.
val remainingDuration = if (animationDuration != null && animationStart != null) {
    (animationDuration - Duration.between(animationStart, Instant.now()))
        .toMillis()
        .coerceAtLeast(0L)
} else {
    0L
}

Java

// Get the duration of the animated vector drawable.
Duration animationDuration = splashScreenView.getIconAnimationDuration();
// Get the start time of the animation.
Instant animationStart = splashScreenView.getIconAnimationStart();
// Calculate the remaining duration of the animation.
long remainingDuration;
if (animationDuration != null && animationStart != null) {
    remainingDuration = animationDuration.minus(
            Duration.between(animationStart, Instant.now())
    ).toMillis();
    remainingDuration = Math.max(remainingDuration, 0L);
} else {
    remainingDuration = 0L;
}

Risorse aggiuntive