Pular para o conteúdo
charmotion

Ícone animado na splash screen do Android: especificações, XML e transição

Por equipe Charmotion · Atualizado em

Ilustração de capa do guia: ícone animado na splash screen do Android: especificações, XML e transição, com personagens de demonstração do Charmotion

Um ícone animado na splash do Android precisa ser um AnimatedVectorDrawable em um canvas de 432 dp, com a parte visível dentro dos 288 dp internos. O Google recomenda manter a animação em até 1.000 ms em celulares, com qualquer atraso de início de no máximo 166 ms. A animação funciona no Android 12 e posteriores; em versões anteriores, a biblioteca de compatibilidade androidx mostra um ícone estático.

Principais pontos

  • Só um AnimatedVectorDrawable pode ser animado na splash do sistema; Lottie, GIF e sequências de PNG não podem.
  • Desenhe em um canvas de 432 dp e mantenha o conteúdo visível dentro dos 288 dp internos (dois terços).
  • No Android 12 (com target API 31 ou 32), defina windowSplashScreenAnimationDuration; o Android 13 lê a duração a partir do AVD.
  • Defina android:windowSplashScreenBehavior como icon_preferred no Android 13+ para que o ícone sempre apareça.
  • Use setOnExitAnimationListener para fazer a splash sumir com fade e passar para uma intro completa na sua primeira tela.

Já tem um personagem ou logo? Veja seu personagem em telas reais de app: telas de splash, onboarding, carregamento e estado vazio. É grátis, roda no navegador e não envia nada.

Quais são as especificações do ícone da splash screen do Android?

Estes dados vêm da documentação de splash screen do Google e da referência SplashScreen do androidx (Android Developers):

ItemEspecificação
Formato do ícone animadoXML AnimatedVectorDrawable (AVD)
Área do ícone animado432 dp (quatro vezes um ícone adaptável); os dois terços internos, 288 dp, ficam visíveis
Ícone estático com fundo de ícone240×240 dp, conteúdo dentro de um círculo de 160 dp
Ícone estático sem fundo de ícone288×288 dp, conteúdo dentro de um círculo de 192 dp
Imagem da marca (opcional)200×80 dp
FundoUma única cor, windowSplashScreenBackground
Duração da animaçãoRecomenda-se não passar de 1.000 ms em celulares
Atraso antes do inícioNo máximo 166 ms
Inicialização lentaSe a inicialização levar mais de 1.000 ms, considere uma animação em loop
Animado emAndroid 12 (API 31) e posteriores

A biblioteca de compatibilidade androidx.core:core-splashscreen leva a mesma splash a dispositivos a partir da API 23, mas a referência é explícita: antes da API 31, o comportamento da plataforma é replicado "com exceção do suporte a Animated Vector Drawable" (referência do androidx). Coloque o drawable animado em res/drawable-v31 e uma versão estática em res/drawable.

Como configurar um ícone animado de splash em XML?

Você precisa de três partes: o AVD, um tema inicial e uma chamada na sua activity de inicialização. Um AVD mínimo que faz uma forma surgir com overshoot (substitua o path pelos paths vetoriais do seu ícone, mantidos dentro dos 288 dp centrais):

<!-- res/drawable-v31/splash_icon.xml -->
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:aapt="http://schemas.android.com/aapt">
  <aapt:attr name="android:drawable">
    <vector android:width="432dp" android:height="432dp"
        android:viewportWidth="432" android:viewportHeight="432">
      <group android:name="icon" android:pivotX="216" android:pivotY="216">
        <path android:fillColor="#FFFFFF"
            android:pathData="M216,136a80,80 0 1,1 0,160a80,80 0 1,1 0,-160z" />
      </group>
    </vector>
  </aapt:attr>
  <target android:name="icon">
    <aapt:attr name="android:animation">
      <set>
        <objectAnimator android:propertyName="scaleX" android:duration="600"
            android:valueFrom="0.6" android:valueTo="1"
            android:interpolator="@android:interpolator/overshoot" />
        <objectAnimator android:propertyName="scaleY" android:duration="600"
            android:valueFrom="0.6" android:valueTo="1"
            android:interpolator="@android:interpolator/overshoot" />
      </set>
    </aapt:attr>
  </target>
</animated-vector>

O tema inicial, usando a biblioteca de compatibilidade:

<!-- res/values/themes.xml -->
<style name="Theme.App.Starting" parent="Theme.SplashScreen">
  <item name="windowSplashScreenBackground">@color/brand_background</item>
  <item name="windowSplashScreenAnimatedIcon">@drawable/splash_icon</item>
  <item name="windowSplashScreenAnimationDuration">600</item>
  <item name="postSplashScreenTheme">@style/Theme.App</item>
</style>

<!-- res/values-v33/themes.xml: same style, plus -->
<item name="android:windowSplashScreenBehavior">icon_preferred</item>

Defina android:theme="@style/Theme.App.Starting" na application ou na activity de inicialização no manifest e depois chame installSplashScreen() antes de super.onCreate(), como mostra o guia de migração do Google (Android Developers).

icon_preferred existe porque, por padrão no Android 13 e posteriores, o sistema pode mostrar a splash sem o ícone, dependendo de como a activity foi iniciada. O Google recomenda defini-lo se você nunca quiser uma splash vazia e quiser sempre exibir o ícone animado.

Como controlar por quanto tempo o ícone da splash é animado?

Há duas coisas diferentes que é fácil confundir: quanto tempo o ícone fica animando e quanto tempo a splash fica na tela.

  • Android 12 (apps com target API 31 ou 32): defina windowSplashScreenAnimationDuration para que a animação toque enquanto a janela inicial é exibida. Segundo o Google, isso não é necessário no Android 13, porque a duração é inferida diretamente do AnimatedVectorDrawable.
  • O atributo nunca prolonga a splash. Tanto o guia do Google quanto a referência do androidx dizem que ele não afeta o tempo de exibição da splash; na biblioteca de compatibilidade, ele só alimenta SplashScreenViewProvider.iconAnimationDurationMillis.
  • Para manter a splash na tela enquanto você carrega, use splashScreen.setKeepOnScreenCondition { !viewModel.isReady }. A condição é verificada antes de cada desenho, então mantenha-a leve.

Respeite a recomendação de 1.000 ms para a animação do ícone em si. Se o seu app costuma demorar mais do que isso para iniciar, crie o AVD de forma que o estado final possa ficar em loop ou parado com calma, em vez de esticar um único movimento. E se o app estiver pronto em 300 ms, deixe a splash sair: ninguém abriu o seu app para ficar olhando para ela.

Por que não dá para colocar Lottie, GIF ou sequência de PNG na splash?

Porque o sistema desenha a splash a partir do seu tema como uma janela inicial, antes de a sua activity desenhar qualquer coisa, e o único drawable animado aceito ali é o XML de AnimatedVectorDrawable indicado em windowSplashScreenAnimatedIcon. Um arquivo Lottie precisa da biblioteca Lottie rodando dentro do seu processo, um GIF precisa de um decodificador e de uma view, e uma sequência de PNG é só uma lista de bitmaps. Nenhum deles pode ser referenciado por um atributo de tema.

Isso também mostra o que um AVD faz bem e o que não faz. Ele anima paths vetoriais, grupos e suas propriedades (rotação, escala, translação, morphing de path, alfa). Um logo plano e geométrico se adapta sem problemas. Um personagem detalhado, um ícone cheio de gradientes ou 3D, ou qualquer coisa raster, não; forçar isso costuma exigir simplificar a arte.

A divisão prática: mantenha a splash do sistema simples (um ícone estático ou um AVD curto que surge na tela) e toque a animação elaborada dentro do app, onde Lottie, Rive e vídeo funcionam. Compare as opções em Lottie vs Rive vs vídeo para splash screen.

Como fazer a transição da splash para uma intro completa?

Registre um listener de saída. Depois que ele é definido, a splash deixa de ser removida automaticamente, e você chama remove() quando a sua animação de saída termina (referência do androidx):

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        val splash = installSplashScreen()
        super.onCreate(savedInstanceState)

        splash.setOnExitAnimationListener { provider ->
            provider.view.animate()
                .alpha(0f)
                .setDuration(200L)
                .withEndAction { provider.remove() }
                .start()
        }
        setContentView(R.layout.activity_intro)  // first screen plays the intro
    }
}

A primeira tela usa a mesma cor de fundo, com o ícone no mesmo tamanho e centralizado, então o fade revela o que parece ser o mesmo ícone, que em seguida começa a intro completa. Com um arquivo Rive, a view legada pode tocar uma state machine de abertura direto do XML:

<app.rive.runtime.kotlin.RiveAnimationView
    android:id="@+id/intro"
    android:layout_width="240dp"
    android:layout_height="240dp"
    android:layout_gravity="center"
    app:riveResource="@raw/launch"
    app:riveStateMachine="LaunchStateMachine" />

Depois, espere a duração da intro antes de seguir. Uma LaunchStateMachine do Charmotion toca uma intro de 2,6 segundos uma vez, termina no ícone em repouso e não dispara nenhum evento de fim, então agende o próximo passo com um timer (por exemplo, intro.postDelayed({ showHome() }, 2600)) em vez de esperar um callback. A documentação Android do Rive explica a configuração com Rive.init(context) (Rive).

O Charmotion não exporta AnimatedVectorDrawable. Os arquivos dele cobrem a parte dessa transição que acontece dentro do app (.riv, WebM com fundo transparente e MOV HEVC, MP4); o AVD da splash do sistema é algo que você desenha em formato vetorial ou mantém como ícone estático.

O que mais dá errado com ícones de splash no Android?

  • Arte cortada. O conteúdo fora do círculo interno de dois terços é mascarado. Desenhe dentro de 288 dp do canvas de 432 dp para o ícone animado, ou de 192 dp de 288 dp para um estático.
  • Um ícone adaptativo reaproveitado como ícone da splash em versões antigas. A referência do androidx avisa que, antes da API 31, um ícone adaptativo em windowSplashScreenAnimatedIcon é cortado e redimensionado; ela sugere usar a camada de primeiro plano e a cor de fundo do ícone.
  • Esperar animação abaixo do Android 12. A biblioteca de compatibilidade mostra o ícone estático. Inclua o drawable animado apenas em drawable-v31.
  • installSplashScreen() depois de super.onCreate() ou um postSplashScreenTheme ausente, o que deixa a activity presa no tema da splash.
  • Uma animação que dura mais que a inicialização. Depois de mais ou menos um segundo, o usuário percebe que está esperando um logo. Mantenha o AVD curto e deixe a intro dentro do app transmitir a personalidade.

Para a visão multiplataforma, incluindo iOS, veja animação de abertura e splash screen de apps.

Como adicionar um ícone animado à splash screen do Android

  1. Desenhe o AVD. Crie um AnimatedVectorDrawable em um canvas de 432 dp com o conteúdo visível dentro dos 288 dp centrais, com animação de no máximo cerca de 1.000 ms.
  2. Separe por nível de API. Coloque o drawable animado em res/drawable-v31 e uma versão estática em res/drawable para dispositivos mais antigos.
  3. Crie o tema inicial. Estenda Theme.SplashScreen, defina windowSplashScreenBackground, windowSplashScreenAnimatedIcon, windowSplashScreenAnimationDuration e postSplashScreenTheme e adicione icon_preferred em values-v33.
  4. Instale. Aplique o tema no manifest e chame installSplashScreen() antes de super.onCreate().
  5. Faça a transição. Use setOnExitAnimationListener para fazer o fade out da splash e, em seguida, toque a intro completa em uma primeira tela com o mesmo fundo, esperando a duração dela antes de mostrar o app.

Perguntas frequentes

Posso usar um arquivo Lottie como ícone da splash no Android?

Não. O ícone da splash vem de um atributo de tema, e a forma animada precisa ser um AnimatedVectorDrawable. O Lottie precisa da biblioteca rodando no seu app, então toque a animação Lottie na primeira tela depois que a splash sair, com a mesma cor de fundo.

O windowSplashScreenAnimationDuration mantém a splash na tela por mais tempo?

Não. A documentação do Google diz que ele não afeta por quanto tempo a splash screen é exibida. Ele informa ao Android 12 por quanto tempo rodar a animação do ícone. Para manter a splash enquanto o app carrega, use setKeepOnScreenCondition.

A splash screen do Android pode mostrar uma imagem de marca?

Sim. Além do ícone central, a splash screen pode mostrar uma imagem de marca opcional na parte inferior, com 200×80 dp segundo a documentação do Google. Mantenha-a simples, já que ela fica sobre a mesma cor de fundo única e aparece em toda inicialização a frio.

O que o icon_preferred faz?

No Android 13 e posteriores, android:windowSplashScreenBehavior definido como icon_preferred faz o sistema sempre mostrar o seu ícone na splash, em vez de às vezes mostrar uma splash vazia dependendo de como a activity foi iniciada.

Respostas rápidas deste guia

Fontes

Guias relacionados