O Android 12 oferece a API SplashScreen
,
que ativa uma nova animação de inicialização para todos os apps. Ela inclui um
movimento de entrada no app ao iniciar, uma tela de apresentação mostrando o ícone do app e uma
transição para ele.

A nova experiência fornece elementos de design padrão a cada inicialização do app, mas também é personalizável para que os apps possam manter o branding exclusivo.
Como a tela de apresentação funciona
Quando um usuário iniciar um app enquanto o processo do app não estiver em execução (uma inicialização a frio) ou se a atividade ainda não foi criada (uma inicialização lenta), os eventos a seguir ocorrerão. A tela de apresentação nunca será exibida durante uma inicialização a quente.
O sistema mostrará a tela de apresentação usando temas e todas as animações que você definiu.
Quando o app estiver pronto, a tela de apresentação será dispensada e o app será exibido.
Elementos e mecânica da animação
Os elementos da animação são definidos por arquivos de recurso XML no manifesto do Android. Há versões para os modos claro e escuro.
Elas são formadas pelo segundo plano da janela, o ícone animado do app e o segundo plano do ícone:

Esteja ciente das seguintes considerações a respeito desses elementos:
O ícone do app (1) precisa ser um drawable vetorial, podendo ser estático ou animado. Embora as animações possam ter uma duração ilimitada, recomendamos que não exceda 1.000 milissegundos. Por padrão, o ícone na tela de início será usado.
O ícone em segundo plano (2) é opcional e é útil se mais contraste for necessário entre o ícone e o segundo plano da janela. Se você usar um ícone adaptativo, o segundo plano dele será exibido se houver contraste suficiente com o segundo plano da janela.
Assim como para ícones adaptativos, ⅓ do primeiro plano será mascarado (3).
O segundo plano da janela (4) consiste em uma única cor opaca. Se o segundo plano da janela estiver definido e tiver uma cor simples, ele será usado por padrão se o atributo não estiver definido.
A mecânica da animação da tela de apresentação consiste em animações de entrada e saída.
A animação de entrada consiste na visualização do sistema para a tela de apresentação. Isso é controlado pelo sistema e não pode ser personalizado.
A animação de saída consiste na execução da animação que oculta a tela de apresentação. Se você quiser personalizá-la, terá acesso à
SplashScreenView
e ao ícone dela e poderá executar qualquer animação neles, com as configurações de transformação, opacidade e cor. Nesse caso, a tela inicial precisará ser removida manualmente quando a animação for concluída.
Personalizar a tela de apresentação no app
Por padrão, a SplashScreen
usa o windowBackground
do tema se ele tiver uma
só cor e o ícone na tela de início. A personalização da tela de apresentação é
realizada adicionando atributos ao tema do app.
Você pode personalizar a tela de apresentação do app das seguintes maneiras:
Definindo atributos de tema para mudar a aparência
Mantendo a apresentação na tela por mais tempo
Personalizando a animação para dispensar a tela de apresentação.
Definir um tema para a tela de apresentação para mudar a aparência dela
Você pode especificar os atributos a seguir no tema da atividade para personalizar a
tela de apresentação do app. Se você já tiver uma implementação de tela de apresentação
legada que use atributos como o android:windowBackground
, considere
fornecer um arquivo de recurso alternativo para o Android 12.
Use
windowSplashScreenBackground
para preencher o plano de fundo com uma única cor específica:<item name="android:windowSplashScreenBackground">@color/...</item>
Use
windowSplashScreenAnimatedIcon
para substituir um ícone no centro da janela inicial. Se o objeto for animado e um drawable que usaAnimationDrawable
eAnimatedVectorDrawable
, ele também fará a animação ao exibir a janela inicial.<item name="android:windowSplashScreenAnimatedIcon">@drawable/...</item>
Use
windowSplashScreenAnimationDuration
para definir o período de exibição da tela de apresentação antes de ser dispensada. O tempo máximo é de 1.000 ms.Use
windowSplashScreenIconBackground
para definir um plano de fundo por trás do ícone da tela de apresentação. Isso é útil quando não há contraste suficiente entre o plano de fundo da janela e o ícone.<item name=”android:windowSplashScreenIconBackground”>@color/...</item>
Se quiser, use
windowSplashScreenBrandingImage
para definir a imagem que será exibida na parte inferior da tela de apresentação. As diretrizes de design recomendam não usar uma imagem de marca.<item name=”android:windowSplashScreenBrandingImage”>@drawable/...</item>
Manter a apresentação na tela por mais tempo
A tela de apresentação é dispensada assim que o app exibe o primeiro frame. Se você
precisar carregar uma pequena quantidade de dados, como as configurações do tema do app usando um disco
local de forma assíncrona, use ViewTreeObserver.OnPreDrawListener
para suspender o app e desenhar o primeiro frame.
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 if the initial data is ready. return if (viewModel.isReady) { // The content is ready; start drawing. content.viewTreeObserver.removeOnPreDrawListener(this) true } else { // The content is not 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 if the initial data is ready. if (mViewModel.isReady()) { // The content is ready; start drawing. content.getViewTreeObserver().removeOnPreDrawListener(this); return true; } else { // The content is not ready; suspend. return false; } } }); }
Personalizar a animação para dispensar a tela de apresentação
Você pode personalizar ainda mais a animação da tela de apresentação usando
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(); }); }
No início deste callback, o drawable vetorial animado
na tela de apresentação foi iniciado. Dependendo da duração da inicialização do app,
o drawable poderá estar no meio da animação. Use
SplashScreenView.getIconAnimationStartMillis
para saber quando a animação começou. Você pode calcular a duração restante da animação do
ícone desta maneira:
Kotlin
// Get the duration of the animated vector drawable. val animationDuration = splashScreenView.iconAnimationDurationMillis // Get the start time of the animation. val animationStart = splashScreenView.iconAnimationDurationMillis // Calculate the remaining duration of the animation. val remainingDuration = ( animationDuration - (SystemClock.uptimeMillis() - animationStart) ).coerceAtLeast(0L)
Java
// Get the duration of the animated vector drawable. long animationDuration = splashScreenView.getIconAnimationDurationMillis(); // Get the start time of the animation. long animationStart = splashScreenView.getIconAnimationStartMillis(); // Calculate the remaining duration of the animation. long remainingDuration = Math.max( animationDuration - (SystemClock.uptimeMillis() - animationStart), 0L );