Fornecer navegação personalizada no sentido contrário

A navegação de retorno é a forma como os usuários se movem para trás no histórico de telas que eles visitaram anteriormente. Todos os dispositivos Android oferecem um botão "Voltar" para esse tipo de navegação, então não adicione um botão "Voltar" à IU do seu app. Dependendo do dispositivo Android do usuário, esse botão pode ser um botão físico ou de software.

O Android mantém uma pilha de retorno de destinos à medida que o usuário navega no seu app. Isso permite que o Android navegue corretamente para destinos anteriores quando o botão "Voltar" é pressionado. No entanto, há alguns casos em que seu app pode precisar implementar um comportamento de retorno próprio para fornecer a melhor experiência do usuário possível.

Por exemplo, ao usar um WebView, convém modificar o comportamento padrão do botão "Voltar" para permitir que o usuário navegue de volta pelo histórico de navegação da Web em vez das telas anteriores no seu app.

O Android 13 e versões mais recentes incluem um gesto de volta preditivo para os dispositivos Android. Para saber mais sobre esse recurso, consulte Adicionar suporte ao gesto de volta preditivo.

Implementar a navegação de retorno personalizada

ComponentActivity, a classe base de FragmentActivity e AppCompatActivity, permite controlar o comportamento do botão "Voltar" usando o OnBackPressedDispatcher, que você pode extrair chamando getOnBackPressedDispatcher().

O OnBackPressedDispatcher controla como os eventos do botão "Voltar" são enviados para um ou mais objetos OnBackPressedCallback. O construtor de OnBackPressedCallback aceita um valor booleano para o estado inicial ativado. Quando um callback é ativado, ou seja, isEnabled() retorna true, o agente chama o handleOnBackPressed() do callback para processar o evento do botão "Voltar". Você pode alterar o estado ativado chamando setEnabled().

Os callbacks são adicionados usando os métodos addCallback. Recomendamos usar o método addCallback(), que usa um LifecycleOwner. Isso garante que OnBackPressedCallback seja adicionado somente quando LifecycleOwner for Lifecycle.State.STARTED. A atividade também remove callbacks registrados quando o LifecycleOwner associado é destruído, o que evita vazamentos de memória e torna o LifecycleOwner adequado para uso em fragmentos ou outros proprietários de ciclo de vida que têm um ciclo de vida menor do que a atividade.

Confira um exemplo de implementação de callback:

Kotlin

class MyFragment : Fragment() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // This callback is only called when MyFragment is at least started
        val callback = requireActivity().onBackPressedDispatcher.addCallback(this) {
            // Handle the back button event
        }

        // The callback can be enabled or disabled here or in the lambda
    }
    ...
}

Java

public class MyFragment extends Fragment {

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // This callback is only called when MyFragment is at least started
        OnBackPressedCallback callback = new OnBackPressedCallback(true /* enabled by default */) {
            @Override
            public void handleOnBackPressed() {
                // Handle the back button event
            }
        };
        requireActivity().getOnBackPressedDispatcher().addCallback(this, callback);

        // The callback can be enabled or disabled here or in handleOnBackPressed()
    }
    ...
}

É possível fornecer vários callbacks usando addCallback(). Quando você faz isso, os callbacks são invocados na ordem inversa à da ordem em que foram adicionados. O último callback adicionado é o primeiro que tem a chance de processar o evento do botão "Voltar". Por exemplo, se você adicionar três callbacks chamados one, two e three, nessa ordem, eles serão invocados na ordem three, two, one.

Os callbacks seguem o padrão Cadeia de responsabilidade. Cada callback na cadeia será invocado somente se o callback anterior não tiver sido ativado. Isso significa que, no exemplo anterior, o callback two será invocado somente se o callback three não estiver ativado, e o callback one só será invocado se o callback two não estiver ativado.

Quando o callback é adicionado usando addCallback(), ele não é adicionado à cadeia de responsabilidade até que LifecycleOwner entre no estado Lifecycle.State.STARTED.

Recomendamos mudar o estado ativado no OnBackPressedCallback para mudanças temporárias, porque isso mantém a ordem descrita acima. Isso é especialmente importante se você tem callbacks registrados em vários proprietários de ciclo de vida aninhados.

Nos casos em que você quiser remover o OnBackPressedCallback completamente, chame remove(). Isso geralmente não é necessário, porque os callbacks são removidos automaticamente quando o LifecycleOwner associado é destruído.

Atividade onBackPressed()

Se você estiver usando onBackPressed() para processar eventos do botão "Voltar", recomendamos o uso de um OnBackPressedCallback. No entanto, se você não puder fazer essa alteração, as seguintes regras serão aplicáveis:

  • Todos os callbacks registrados por addCallback serão avaliados quando você chamar super.onBackPressed().
  • No Android 12 (nível 32 da API) e em versões anteriores, onBackPressed é sempre chamado, independente de qualquer instância registrada de OnBackPressedCallback.