Schermate iniziali

A partire da Android 12, l'API SplashScreen consente alle app di avviarsi con animazione, inclusa un'animazione all'interno dell'app all'avvio, una schermata iniziale che mostra l'icona dell'app e una transizione all'app stessa. Un SplashScreen è un Window e quindi copre un Activity.

Figura 1. Una schermata iniziale.

L'esperienza della schermata iniziale offre elementi di design standard a ogni avvio dell'app, ma è anche personalizzabile in modo che la tua app possa mantenere il proprio branding unico.

Oltre a utilizzare l'API della piattaforma SplashScreen, puoi anche utilizzare la libreria di compatibilità SplashScreen, che avvolge l'API SplashScreen.

Come funziona la schermata iniziale

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

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

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

La schermata di benvenuto non viene mai visualizzata durante un avvio a caldo.

Elementi e funzionamento della schermata iniziale

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

Gli elementi personalizzabili di una schermata iniziale sono l'icona dell'app, lo sfondo dell'icona e lo sfondo della finestra:

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

Considera i seguenti elementi, mostrati nella figura 2:

1 L'icona dell'app deve essere un drawable vettoriale. Puoi scegliere tra un'immagine statica o animata. Sebbene le animazioni possano avere una durata illimitata, consigliamo di non superare i 1000 millisecondi. L'icona del programma di avvio è 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 adattabile, il suo sfondo viene visualizzato se è presente un contrasto sufficiente con lo sfondo della finestra.

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

4 Lo sfondo della finestra è costituito da un singolo 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 della schermata iniziale

L'icona della schermata iniziale utilizza le stesse specifiche delle icone adattabili, come segue:

  • Immagine del brand: deve avere una dimensione di 200 x 80 dp.
  • Icona dell'app con sfondo: deve avere dimensioni di 240 x 240 dp e rientrare in un cerchio di 160 dp di diametro.
  • Icona dell'app senza sfondo: deve avere dimensioni di 288 x 288 dp e rientrare in un cerchio di 192 dp di diametro.

Ad esempio, se le dimensioni complete di un'immagine sono 300 x 300 dp, l'icona deve rientrare in un cerchio con un diametro di 200 dp. Tutto ciò che si trova al di fuori del cerchio diventa invisibile (mascherato).

Un'immagine che mostra diverse dimensioni delle icone per sfondo a tinta unita e trasparente
Figura 3. Dimensioni dell'icona della schermata iniziale per sfondi solidi e trasparenti, rispettivamente.

Animazioni della schermata iniziale e sequenza di avvio

Spesso è associata una latenza aggiuntiva al lancio di un'app con un avvio completo. L'aggiunta di un'icona animata alla schermata iniziale ha un evidente appeal estetico e offre un'esperienza più premium. La ricerca sugli utenti mostra che il tempo di avvio percepito è inferiore quando si visualizza un'animazione.

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

Un'immagine che mostra la sequenza di lancio in dodici fotogrammi consecutivi, a partire dal tocco dell'icona del programma di avvio e dal riempimento dello schermo man mano che si ingrandisce
Figura 4. Sequenza di lancio.
  1. Animazione di entrata: è composta dalla visualizzazione del sistema alla schermata di benvenuto. È controllato dal sistema e non è personalizzabile.

  2. Schermata iniziale (mostrata durante la parte "attesa" della sequenza): la schermata iniziale può essere personalizzata, consentendoti di fornire il tuo logo animato e il tuo branding. Per funzionare correttamente, deve soddisfare i requisiti descritti in questa pagina.

  3. Animazione di uscita: è costituita dall'animazione che nasconde la schermata iniziale. Se vuoi personalizzarlo, utilizza SplashScreenView e la relativa icona. Puoi applicare qualsiasi animazione, con impostazioni per trasformazione, opacità e colore. In questo caso, rimuovi manualmente la schermata iniziale al termine dell'animazione.

Quando viene eseguita l'animazione dell'icona, l'avvio dell'app ti offre la possibilità di saltare la sequenza se l'app è pronta prima. L'app si attiva onResume() o la schermata iniziale scade automaticamente, quindi assicurati che il movimento possa essere tralasciato comodamente. La schermata iniziale deve essere ignorata con onResume() solo quando l'app è stabile dal punto di vista visivo, pertanto non sono necessari altri spinner. L'introduzione di un'interfaccia incompleta può essere spiacevole per gli utenti e potrebbe dare un'impressione di imprevedibilità o mancanza di rifinitura.

Requisiti dell'animazione della schermata iniziale

La schermata di benvenuto deve rispettare le seguenti specifiche:

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

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

    • Formato: l'icona deve essere un file XML AnimatedVectorDrawable (AVD).
    • Dimensioni: un'icona AVD deve avere le dimensioni quattro volte superiori a quelle di un'icona adattabile, come segue:
      • L'area dell'icona deve essere di 432 dp, ovvero quattro volte l'area di 108 dp di un'icona adattabile non mascherata.
      • I due terzi interni dell'immagine sono visibili nell'icona del programma di avvio e devono essere pari a 288 dp, ovvero quattro volte i 72 dp che costituiscono l'area mascherata interna di un'icona adattabile.
    • Durata: consigliamo di non superare i 1000 ms sui telefoni. Puoi utilizzare un inizio ritardato, ma non più lungo di 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 la tua app disegna il primo frame. Puoi personalizzare ulteriormente questa opzione come descritto nella sezione relativa al mantenimento della schermata iniziale sullo schermo per periodi più lunghi.

Risorse della schermata iniziale

Figura 5. AVD di esempio.

Scarica il kit di avvio di esempio, che mostra come creare, formattare ed esportare un'animazione in un AVD. Sono inclusi i seguenti elementi:

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

Se scarichi questi file, accetti i Termini di servizio di Google.

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

Personalizzare la schermata iniziale nell'app

Per impostazione predefinita, SplashScreen utilizza il windowBackground del tema se windowBackground è un singolo colore. Per personalizzare la schermata iniziale, aggiungi gli 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.

  • Mantieni il dispositivo sullo schermo per un periodo di tempo più lungo.

  • Personalizza l'animazione per la chiusura della schermata iniziale.

Inizia

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

Groovy

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

Kotlin

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

Impostare un tema per la schermata iniziale per modificarne l'aspetto

Puoi specificare i seguenti attributi nel tema Activity per personalizzare la schermata iniziale della tua app. Se hai già un'implementazione della schermata iniziale precedente che utilizza attributi come android:windowBackground, ti consigliamo 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 di avvio.

    Per le app che hanno come target solo Android 12 (livello API 32), svolgi i seguenti passaggi:

    Se l'oggetto è animabile e può essere disegnato tramite AnimationDrawable e AnimatedVectorDrawable, imposta windowSplashScreenAnimationDuration su riproduci l'animazione mentre viene mostrata la finestra di avvio. Questo passaggio non è obbligatorio 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 di questo valore non influisce sul tempo effettivo durante il quale viene visualizzata la schermata iniziale, ma puoi recuperarlo quando personalizzi l'animazione di uscita della schermata iniziale utilizzando SplashScreenView.getIconAnimationDuration. Per ulteriori 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 per il design sconsigliano di utilizzare un'immagine del brand.

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

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

Mantieni la schermata iniziale sullo schermo per periodi più lunghi

La schermata iniziale viene chiusa non appena l'app disegna il primo frame. Se devi caricare una piccola quantità di dati, ad esempio il caricamento delle 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 del disegno, ad esempio non impostando la visualizzazione dei contenuti e terminando prima di onResume, l'ascoltatore pre-draw 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;
                    }
                }
            });
}

Personalizzare l'animazione per la chiusura della 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 di avvio. A seconda della durata del lancio dell'app, il drawable potrebbe essere nel mezzo dell'animazione. Utilizza SplashScreenView.getIconAnimationStart per sapere quando è iniziata l'animazione. Puoi calcolare la durata rimanente dell'animazione dell'icona nel seguente modo:

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