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. Assim, você não precisa adicioná-lo à 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 normalmente permite que o Android navegue adequadamente para destinos anteriores quando o botão "Voltar" é pressionado. No entanto, há casos em que seu app precisa 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.

Implementar a navegação de volta personalizada

ComponentActivity, a classe base de FragmentActivity e AppCompatActivity, permite controlar o comportamento do botão "Voltar" usando 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. Somente quando um callback estiver ativado (isto é, isEnabled() retorna true), o agente chamará o handleOnBackPressed() do callback para manipular o evento do botão "Voltar". Você pode alterar o estado ativado chamando setEnabled().

Os callbacks são adicionados por meio dos métodos addCallback. É altamente recomendável 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 os callbacks registrados quando o LifecycleOwner associado é destruído, o que evita vazamentos de memória e o torna adequado para uso em fragmentos ou outros proprietários de ciclo de vida que têm um ciclo de vida mais curto que a atividade.

Veja um exemplo de implementação de callback:

Kotlin

class MyFragment : Fragment() {

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

        // This callback will only be 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 will only be 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()
    }
    ...
}

Você pode fornecer vários callbacks por meio de addCallback(). Ao fazer isso, os callbacks são invocados na ordem inversa em que são adicionados. O último callback adicionado é o primeiro que tem a chance de manipular o evento do botão "Voltar". Por exemplo, se você tiver adicionado três callbacks (one, two e three) em ordem, eles serão invocados na ordem de three, two e one, respectivamente.

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 seria invocado somente se o callback three não tivesse sido ativado. O callback one seria invocado somente se o callback two não tivesse sido ativado e assim por diante.

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

Alterar o estado ativado em OnBackPressedCallback é altamente recomendável para alterações temporárias porque mantém a ordem descrita acima, o que será particularmente importante se você tiver callbacks registrados em vários proprietários diferentes do ciclo de vida aninhado.

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

Atividade onBackPressed()

Se você estiver usando onBackPressed() para lidar com eventos do botão "Voltar", recomendamos o uso de OnBackPressedCallback. No entanto, se você não conseguir fazer essa alteração, as regras abaixo 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.