Iniciar uma atividade usando uma animação

As transições de atividades em aplicativos com Material Design fornecem conexões visuais entre estados diferentes por meio de movimentos e transformações entre elementos comuns. Você pode especificar animações personalizadas para transições de entrada e de saída e para transições de elementos compartilhados entre atividades.

Figura 1. Uma transição com elementos compartilhados.

  • Uma transição de entrada determina como as visualizações em uma atividade entram em cena. Por exemplo, na transição de entrada explode, as visualizações entram em cena por fora e voam em direção ao centro da tela.
  • Uma transição de saída determina como as visualizações em uma atividade saem de cena. Por exemplo, na transição de saída explode, as visualizações saem de cena a partir do centro.
  • Uma transição de elementos compartilhados determina como as visualizações compartilhadas entre duas atividades fazem transição entre essas atividades. Por exemplo, se duas atividades têm a mesma imagem em posições e tamanhos diferentes, a transição de elemento compartilhado changeImageTransform converte e dimensiona a imagem suavemente entre essas atividades.

O Android é compatível com estas transições de entrada e saída:

  • explode: move as visualizações para dentro ou para fora partindo do centro da cena.
  • deslizar: move as visualizações para dentro ou para fora partindo de um dos cantos da cena.
  • esmaecer: adiciona ou remove uma visualização de uma cena modificando a opacidade dela.

Qualquer transição que amplie a classe Visibility é suportada como uma transição de entrada ou de saída. Para mais informações, consulte a referência da API para a classe Transition.

O Android também é compatível com estas transições de elementos compartilhados:

  • changeBounds: anima as mudanças das visualizações desejadas em limites do layout.
  • changeClipBounds: anima as mudanças das visualizações desejadas em limites de corte.
  • changeTransform: anima as mudanças das visualizações desejadas em escala e rotação.
  • changeImageTransform: anima as mudanças das imagens desejadas em tamanho e escala.

Ao ativar as transições de atividades no seu aplicativo, a transição de esmaecimento cruzado padrão é ativada entre as atividades de entrada e saída.

Figura 2: uma transição de cena com um elemento compartilhado.

Para ver o código de exemplo que executa a animação entre atividades usando elementos compartilhados, consulte ActivitySceneTransitionBasic.

Verificar a versão do sistema

As APIs de transição de atividade estão disponíveis no Android 5.0 (API 21) e versões posteriores. Para preservar a compatibilidade com versões anteriores do Android, verifique a version do sistema em execução antes de chamar as APIs para quaisquer destes recursos:

Kotlin

    // Check if we're running on Android 5.0 or higher
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        // Apply activity transition
    } else {
        // Swap without transition
    }
    

Java

    // Check if we're running on Android 5.0 or higher
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        // Apply activity transition
    } else {
        // Swap without transition
    }
    

Especificar transições personalizadas

Primeiro, ative as transições de conteúdo da janela com o atributo android:windowActivityTransitions ao definir um estilo herdado do tema do material. Você também pode especificar transições de entrada, saída e elemento compartilhado na definição de estilo:

    <style name="BaseAppTheme" parent="android:Theme.Material">
      <!-- enable window content transitions -->
      <item name="android:windowActivityTransitions">true</item>

      <!-- specify enter and exit transitions -->
      <item name="android:windowEnterTransition">@transition/explode</item>
      <item name="android:windowExitTransition">@transition/explode</item>

      <!-- specify shared element transitions -->
      <item name="android:windowSharedElementEnterTransition">
        @transition/change_image_transform</item>
      <item name="android:windowSharedElementExitTransition">
        @transition/change_image_transform</item>
    </style>
    

A transição change_image_transform desse exemplo é definida da seguinte maneira:

    <!-- res/transition/change_image_transform.xml -->
    <!-- (see also Shared Transitions below) -->
    <transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
      <changeImageTransform/>
    </transitionSet>
    

O elemento changeImageTransform corresponde à classe ChangeImageTransform. Para saber mais, consulte a Referência da API para Transition.

Como alternativa, para habilitar transições de conteúdo da janela no código, chame a função Window.requestFeature():

Kotlin

    // inside your activity (if you did not enable transitions in your theme)
    with(window) {
        requestFeature(Window.FEATURE_CONTENT_TRANSITIONS)

        // set an exit transition
        exitTransition = Explode()
    }
    

Java

    // inside your activity (if you did not enable transitions in your theme)
    getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);

    // set an exit transition
    getWindow().setExitTransition(new Explode());
    

Para especificar transições no código, chame as funções a seguir com um objeto Transition:

As funções setExitTransition() e setSharedElementExitTransition() definem a transição de saída para a atividade que faz a chamada. As funções setEnterTransition() e setSharedElementEnterTransition() definem a transição de entrada para a atividade que recebe a chamada.

Para conseguir o efeito completo de uma transição, você precisa ativar as transições de conteúdo de janela tanto na atividade que faz a chamada quanto naquela que a recebe. Caso contrário, a atividade de chamada acionará a transição de saída, mas você verá uma transição de janela (como dimensionar ou esmaecer).

Para iniciar uma transição de entrada o mais cedo possível, use a função Window.setAllowEnterTransitionOverlap() na atividade chamada. Isso faz com que haja transições de entrada mais dramáticas.

Iniciar uma atividade usando transições

Se você ativa as transições e define uma transição de saída para uma atividade, essa transição será ativada ao iniciar outra atividade, como a seguir:

Kotlin

    startActivity(intent,
                  ActivityOptions.makeSceneTransitionAnimation(this).toBundle())
    

Java

    startActivity(intent,
                  ActivityOptions.makeSceneTransitionAnimation(this).toBundle());
    

Se você tiver configurado uma transição de entrada para a segunda atividade, a transição também será ativada quando a atividade for iniciada. Para desativar as transições ao iniciar outra atividade, forneça um pacote de opções null.

Iniciar uma atividade com um elemento compartilhado

Para criar uma animação de transição de tela entre duas atividades que têm um elemento compartilhado:

  1. Ative transições de conteúdo da janela no tema.
  2. Especifique uma transição de elementos compartilhados no estilo.
  3. Defina a transição como um recurso XML.
  4. Atribua um nome comum aos elementos compartilhados em ambos os layouts com o atributo android:transitionName.
  5. Use a função ActivityOptions.makeSceneTransitionAnimation().

Kotlin

    // get the element that receives the click event
    val imgContainerView = findViewById<View>(R.id.img_container)

    // get the common element for the transition in this activity
    val androidRobotView = findViewById<View>(R.id.image_small)

    // define a click listener
    imgContainerView.setOnClickListener( {
        val intent = Intent(this, Activity2::class.java)
        // create the transition animation - the images in the layouts
        // of both activities are defined with android:transitionName="robot"
        val options = ActivityOptions
                .makeSceneTransitionAnimation(this, androidRobotView, "robot")
        // start the new activity
        startActivity(intent, options.toBundle())
    })
    

Java

    // get the element that receives the click event
    final View imgContainerView = findViewById(R.id.img_container);

    // get the common element for the transition in this activity
    final View androidRobotView = findViewById(R.id.image_small);

    // define a click listener
    imgContainerView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Intent intent = new Intent(this, Activity2.class);
            // create the transition animation - the images in the layouts
            // of both activities are defined with android:transitionName="robot"
            ActivityOptions options = ActivityOptions
                .makeSceneTransitionAnimation(this, androidRobotView, "robot");
            // start the new activity
            startActivity(intent, options.toBundle());
        }
    });
    

Para visualizações dinâmicas compartilhadas geradas no código, use a função View.setTransitionName() para especificar um nome de elemento comum em ambas as atividades.

Para reverter a animação de transição de cena ao finalizar a segunda atividade, chame a função Activity.finishAfterTransition() em vez de Activity.finish().

Iniciar uma atividade com diversos elementos compartilhados

Para criar uma animação de transição de cena entre duas atividades que têm mais de um elemento compartilhado, defina os elementos compartilhados em ambos os layouts com o atributo android:transitionName (ou use a função View.setTransitionName() em ambas as atividades) e crie um objeto ActivityOptions, como a seguir:

Kotlin

    // Rename the Pair class from the Android framework to avoid a name clash
    import android.util.Pair as UtilPair
    ...
    val options = ActivityOptions.makeSceneTransitionAnimation(this,
            UtilPair.create(view1, "agreedName1"),
            UtilPair.create(view2, "agreedName2"))
    

Java

    ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(this,
            Pair.create(view1, "agreedName1"),
            Pair.create(view2, "agreedName2"));