Adicionar suporte para o gesto de volta preditivo

Figura 1. Modelo mostrando como funciona o gesto de volta preditivo em um smartphone

A volta preditiva, um recurso de navegação por gestos, permite que os usuários vejam para onde o deslizar para trás os leva.

O gesto "Voltar" pode, por exemplo, mostrar uma visualização animada da tela inicial atrás do app, como apresentado na Figura 1.

A partir do Android 15, a opção para desenvolvedores de animações de volta preditiva não está mais disponível. As animações do sistema, como voltar para a tela inicial, entre tarefas e entre atividades, agora aparecem para apps que ativaram o gesto de volta preditiva totalmente ou no nível da atividade.

É possível testar essa animação de volta à tela inicial, conforme descrito em uma seção a seguir desta página.

Para oferecer suporte ao gesto de volta preditivo, é necessário atualizar o app usando o OnBackPressedCallback compatível com versões anteriores no AndroidX Activity 1.6.0 ou uma API mais recente, ou ainda usando a nova API da plataforma OnBackInvokedCallback. A maioria dos apps usa a API AndroidX compatível com versões anteriores.

Essa atualização oferece um caminho de migração para interceptar corretamente a navegação de retorno, o que envolve substituir essas interceptações em KeyEvent.KEYCODE_BACK e todas as classes com métodos onBackPressed, como Activity e Dialog, pelas novas APIs Back do sistema.

Codelab e vídeo do Google I/O

Além de usar a documentação disponível nesta página, acesse nosso codelab. Ele apresenta a implementação de um caso de uso comum de um WebView que processa o gesto de volta preditivo usando as APIs Activity do AndroidX.

Você também pode assistir ao vídeo do Google I/O, que mostra outros exemplos de implementação das APIs do AndroidX e da plataforma.

Processar gestos de retorno personalizados no Compose

O Compose oferece o elemento combinável PredictiveBackHandler para processar gestos de retorno personalizados. Essa API permite responder ao gesto de retorno e fornece um Flow de objetos BackEventCompat que podem ser usados para implementar animações ou transições personalizadas à medida que o usuário desliza.

Para usar PredictiveBackHandler, verifique se o app inclui a dependência androidx.activity:activity-compose (versão 1.8.0 ou mais recente):

// In your build.gradle.kts file:
dependencies {
    implementation("androidx.activity:activity-compose:1.8.0")
}

PredictiveBackHandler(enabled = isBackHandlerEnabled) { progress: Flow<BackEventCompat> ->
    try {
        progress.collect { backEvent ->
            // Update your UI or animation based on backEvent.progress.
        }
        // Handle the final back action (e.g., navigate back).
    } catch (e: CancellationException) {
        // Back gesture was cancelled, reset your UI.
    }
}

Se você só precisar interceptar o gesto de retorno sem acompanhar o progresso, use BackHandler.

Atualizar um app que usa a navegação de retorno padrão

A volta preditiva está ativada por padrão.

Se o app usa fragmentos ou o componente Navigation, faça upgrade para o AndroidX Activity 1.6.0 ou versões mais recentes.

Atualizar um app que usa uma navegação de retorno personalizada

Existem diferentes caminhos de migração para apps que implementam um comportamento personalizado para a ação "Voltar", dependendo se o app usa o AndroidX e da maneira como ele processa a navegação de retorno.

Como o app processa a navegação de retorno Caminho de migração recomendado (link nesta página)
APIs do AndroidX Migrar uma implementação da ação "Voltar" existente do AndroidX
APIs de plataforma sem suporte Migrar para as APIs do AndroidX um aplicativo AndroidX com APIs de navegação de retorno sem suporte

Migrar a implementação da navegação de retorno do AndroidX

Esse é o caso de uso mais comum e recomendado. Ele se aplica a apps novos ou antigos que processam uma navegação de retorno por gesto personalizada com OnBackPressedDispatcher, conforme descrito em Oferecer navegação de retorno personalizada.

Para garantir que as APIs que já usam OnBackPressedDispatcher (como fragmentos e o componente Navigation) funcionem perfeitamente com o gesto de volta preditivo, faça upgrade para a AndroidX Activity 1.6.0 ou versões mais recentes.

// In your build.gradle file:
dependencies {
    // Add this in addition to your other dependencies
    implementation "androidx.activity:activity:1.6.0"
}

Migrar para as APIs do AndroidX um aplicativo AndroidX com APIs de navegação de retorno sem suporte

Se o app usa as bibliotecas do AndroidX, mas implementa ou referencia APIs de navegação de retorno sem suporte, você precisa migrar para as APIs do AndroidX para conseguir oferecer suporte ao novo comportamento.

Para migrar de APIs sem suporte e passar a usar as APIs do AndroidX:

  1. Migre a lógica de processamento da ação "Voltar" do sistema para o OnBackPressedDispatcher do AndroidX, implementando OnBackPressedCallback. Encontre instruções detalhadas em Oferecer navegação de retorno personalizada.

  2. Desative o OnBackPressedCallback quando estiver tudo pronto para deixar de interceptar o gesto de volta.

  3. Pare de usar OnBackPressed ou KeyEvent.KEYCODE_BACK para interceptar eventos de retorno.

  4. Faça upgrade para o AndroidX Activity 1.6.0 ou uma versão mais recente.

    // In your build.gradle file:
    dependencies {
        // Add this in addition to your other dependencies
        implementation "androidx.activity:activity:1.6.0"
    }
    

Desativar a volta preditiva

Para desativar, em AndroidManifest.xml, na tag <application>, defina a flag android:enableOnBackInvokedCallback como false.

<application
    ...
    android:enableOnBackInvokedCallback="false"
    ... >
...
</application>

Definir como "false" faz o seguinte:

  • A animação do sistema do gesto de volta preditivo será desativada.
  • O OnBackInvokedCallback será ignorado, mas as chamadas de OnBackPressedCallback vão continuar funcionando.

Desativar no nível da atividade

A flag android:enableOnBackInvokedCallback permite desativar as animações preditivas do sistema no nível da atividade. Esse comportamento facilita a migração de apps grandes com várias atividades para gestos de volta preditivos.

O código abaixo mostra um exemplo de enableOnBackInvokedCallback definido para ativar a animação do sistema de volta à tela inicial da MainActivity:

<manifest ...>
    <application . . .

        android:enableOnBackInvokedCallback="false">

        <activity
            android:name=".MainActivity"
            android:enableOnBackInvokedCallback="true"
            ...
        </activity>
        <activity
            android:name=".SecondActivity"
            android:enableOnBackInvokedCallback="false"
            ...
        </activity>
    </application>
</manifest>

Lembre-se das considerações abaixo ao usar a flag android:enableOnBackInvokedCallback:

  • Configurar android:enableOnBackInvokedCallback=false desativa as animações de volta preditiva no nível da atividade ou do app, dependendo de onde a tag foi definida. Além disso, o sistema é instruído a ignorar chamadas para a API OnBackInvokedCallback da plataforma. No entanto, as chamadas para OnBackPressedCallback continuam sendo executadas porque OnBackPressedCallback é compatível com versões anteriores e chama a API onBackPressed, que não tem suporte em versões anteriores ao Android 13.
  • Definir a flag enableOnBackInvokedCallback no nível do app estabelece o valor padrão para todas as atividades nele. Você pode substituir o padrão por atividade definindo a flag no nível da atividade, conforme mostrado no exemplo de código anterior.

Diretrizes de callback

Siga estas diretrizes ao usar os callbacks de sistema com suporte: PredictiveBackHandler ou BackHandler (para Compose), OnBackPressedCallback ou OnBackInvokedCallback.

Determinar o estado da interface que ativa e desativa cada callback

O estado da interface é a propriedade que a descreve. Recomendamos seguir estas etapas gerais.

  1. Determine o estado da interface que ativa e desativa cada callback.

  2. Defina esse estado usando um tipo de detentor de dados observáveis, como StateFlow ou o estado do Compose, e ative ou desative o callback quando o estado mudar.

Se o app estava associando a lógica de retorno às instruções condicionais, isso pode significar que você está reagindo ao evento de retorno depois que ele já ocorreu. Evite esse padrão com callbacks mais recentes. Se possível, retire o callback da instrução condicional e associe-o a um tipo de detentor de dados observáveis.

Usar callbacks de sistema para a lógica da interface

A lógica da interface determina como mostrá-la. Use callbacks de sistema para executar a lógica da interface, como mostrar uma caixa de diálogo ou executar uma animação.

Se o app ativar um OnBackPressedCallback ou um OnBackInvokedCallback com PRIORITY_DEFAULT ou PRIORITY_OVERLAY, as animações de volta preditiva não serão executadas, e você vai precisar processar o evento de retorno. Não crie esses callbacks para executar lógica de negócios ou fazer registros.

Use as abordagens a seguir se o app precisar executar a lógica de negócios ou fazer o registro em log quando o usuário deslizar para trás:

  • No Compose:faça o registro no callback onCleared() de um ViewModel associado ao destino do Compose. Esse é o melhor sinal para saber quando um destino do Compose foi retirado da backstack e destruído.
  • No Android 16 e em versões mais recentes:use OnBackInvokedCallback com PRIORITY_SYSTEM_NAVIGATION_OBSERVER. Isso cria um callback de observador que não consome o evento de retorno. Por exemplo, você pode registrar esse callback quando o usuário desliza para trás da atividade raiz (saindo do app) para registrar o evento de retorno ou executar a lógica de negócios, permitindo que a animação de volta à tela inicial seja reproduzida.
  • Em apps baseados em visualizações:registre em callbacks de ciclo de vida ou backstack em vez de consumir eventos de retorno:
    • Para transições de atividade, verifique se isFinishing é true em Activity.onDestroy().
    • Para transições de fragmentos, verifique se isRemoving é true no ciclo de vida da visualização do fragmento onDestroy() ou use FragmentManager.OnBackStackChangedListener (onBackStackChangeStarted / onBackStackChangeCommitted).

Criar callbacks de responsabilidade única

É possível adicionar vários callbacks ao dispatcher. Eles são adicionados a uma pilha em que o último callback ativo adicionado processa o próximo gesto de volta com um callback por gesto de volta.

É mais fácil gerenciar o estado ativado de um callback se ele tiver uma única responsabilidade. Exemplo:

Ordenação de callbacks em uma pilha no Compose.
Figura 2. Diagrama da pilha de callbacks no Compose.

A Figura 2 mostra como é possível ter vários callbacks na pilha, cada um responsável por uma coisa. No Compose, os callbacks são avaliados do elemento combinável mais interno para o mais externo, e um callback só é executado se os callbacks anteriores a ele na pilha estiverem desativados:

  • A mensagem "Tem certeza de que..." O PredictiveBackHandler é ativado quando o usuário insere dados em um formulário e desativado caso contrário. Quando ativada, ela intercepta o gesto de retorno para mostrar uma caixa de diálogo de confirmação ou uma animação personalizada no app.
  • O BackHandler no nível da tela será executado se o callback anterior estiver desativado. Neste exemplo, ele está desativado.
  • O callback NavHost processa a navegação de retorno para remover destinos da backstack se os callbacks personalizados anteriores estiverem desativados.
  • Por fim, o sistema processa o gesto de retorno se todos os callbacks anteriores estiverem desativados. Quando a backstack está no destino raiz, o sistema aciona animações no nível do sistema, como volta à tela inicial, entre atividades e entre tarefas.

O mesmo comportamento de pilha se aplica a apps baseados em visualização: o último OnBackPressedCallback ativado adicionado tem precedência, voltando para FragmentManager e, por fim, para o processamento de volta do sistema.

Testar a animação do gesto de volta preditivo

A partir do Android 15, as animações do sistema, como voltar para a tela inicial, entre tarefas e entre atividades, são ativadas por padrão para apps que oferecem suporte à navegação de volta preditiva. Elas não estão mais atrás de uma opção para desenvolvedores.

Em dispositivos com Android 13 ou 14, é possível ativar a opção para desenvolvedores e testar a animação de retorno à tela de início mostrada na Figura 1:

  1. No dispositivo, acesse Configurações > Sistema > Opções do desenvolvedor.

  2. Selecione Animações de gestos "Voltar" preditivos.

  3. Inicie o app atualizado e use o gesto "Voltar" para testar o recurso.