O Google tem o compromisso de promover a igualdade racial para as comunidades negras. Saiba como.

Navegar até um destino

A navegação até um destino é feita usando um NavController, um objeto que gerencia a navegação do app dentro de um NavHost. Cada NavHost tem o próprio NavController correspondente. NavController fornece algumas maneiras diferentes de navegar até um destino, que são descritas mais detalhadamente nas seções abaixo.

Para recuperar NavController para um fragmento, uma atividade ou uma visualização, use um dos seguintes métodos:

Kotlin:

Depois de recuperar um NavController, você pode chamar uma das sobrecargas de navigate() para navegar entre destinos. Cada sobrecarga é compatível com vários cenários de navegação, conforme descrito nas seções a seguir.

Usar o Safe Args para navegar com a segurança de tipo

A maneira recomendada de navegar entredestinos é usar o plug-in Safe Args do Gradle. Esse plug-in gera classes de objetos e builders simples que permitem a navegação segura de tipos entre destinos. O Safe Args é altamente recomendado para a navegação e a transmissão de dados entre destinos.

Depois de ativar o Safe Args, o código gerado contém classes e métodos para cada ação definida, bem como classes correspondentes a cada destino de envio e destino.

O Safe Args gera uma classe para cada destino de origem de uma ação. O nome da classe gerada adiciona "Directions" ao nome da classe de destino de origem. Por exemplo, se o destino de origem tem o nome de SpecifyAmountFragment, a classe gerada será chamada SpecifyAmountFragmentDirections.

A classe gerada contém um método estático para cada ação definida no destino de origem. Esse método usa qualquer parâmetro de ação definido como argumentos e retorna um objeto NavDirections que você pode transmitir diretamente para navigate().

Exemplo de Safe Args

Como exemplo, vamos supor que temos um gráfico de navegação com uma única ação que conecta dois destinos, SpecifyAmountFragment e ConfirmationFragment. O ConfirmationFragment usa um único parâmetro float fornecido como parte da ação.

O Safe Args gera uma classe SpecifyAmountFragmentDirections com um único método, actionSpecifyAmountFragmentToConfirmationFragment(), e uma classe interna chamada ActionSpecifyAmountFragmentToConfirmationFragment. A classe interna é derivada de NavDirections e armazena o ID de ação associado e o parâmetro float. O objeto NavDirections retornado pode ser transmitido diretamente para navigate(), conforme mostrado no exemplo a seguir.

Kotlin

    override fun onClick(v: View) {
        val amount: Float = ...
        val action =
            SpecifyAmountFragmentDirections
                .actionSpecifyAmountFragmentToConfirmationFragment(amount)
        v.findNavController().navigate(action)
    }
    

Java

    @Override
    public void onClick(View view) {
        float amount = ...;
        action =
            SpecifyAmountFragmentDirections
                .actionSpecifyAmountFragmentToConfirmationFragment(amount);
        Navigation.findNavController(view).navigate(action);
    }
    

Para ver mais informações sobre como transmitir dados entre destinos com o Safe Args, consulte Usar o Safe Args para transmitir dados com segurança de tipo.

Navegar usando ID

navigate(int) usa o ID do recurso de uma ação ou um destino. O snippet de código a seguir mostra como navegar até ViewTransactionsFragment.

Kotlin

    viewTransactionsButton.setOnClickListener { view ->
       view.findNavController().navigate(R.id.viewTransactionsAction)
    }
    

Java

    viewTransactionsButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Navigation.findNavController(view).navigate(R.id.viewTransactionsAction);
        }
    });

    

Para os botões, você também pode usar o método de conveniência createNavigateOnClickListener() da classe Navigation para navegar até um destino, conforme mostrado no exemplo a seguir.

Kotlin

    button.setOnClickListener(Navigation.createNavigateOnClickListener(R.id.next_fragment, null))
    

Java

    button.setOnClickListener(Navigation.createNavigateOnClickListener(R.id.next_fragment, null));
    

Para gerenciar com outros componentes comuns de IU, por exemplo, a barra de apps superior e a navegação inferior, consulte Atualizar componentes de IU com NavigationUI.

Quando você define uma ação no gráfico de navegação, a navegação gera uma classe NavAction correspondente, que contém as configurações definidas para essa ação, incluindo:

  • Destino: o ID do recurso do destino.
  • Argumentos padrão: um android.os.Bundle contendo valores padrão para o destino, se fornecido.
  • Opções de navegação: opções de navegação, representadas como NavOptions. Essa classe contém toda a configuração especial para a transição para e de volta do destino, incluindo a configuração do recurso de animação, o comportamento de destaque e se o destino precisa ser iniciado no modo superior único.
  • Vamos dar uma olhada em um gráfico de exemplo que consiste em duas telas com uma ação para navegar de uma para outra:

    <?xml version="1.0" encoding="utf-8"?>
        <navigation xmlns:android="http://schemas.android.com/apk/res/android"
                    xmlns:app="http://schemas.android.com/apk/res-auto"
                    xmlns:tools="http://schemas.android.com/tools"
                    android:id="@+id/nav_graph"
                    app:startDestination="@id/a">
    
            <fragment android:id="@+id/a"
                      android:name="com.example.myapplication.FragmentA"
                      android:label="a"
                      tools:layout="@layout/a">
                <action android:id="@+id/action_a_to_b"
                        app:destination="@id/b"
                        app:enterAnim="@anim/nav_default_enter_anim"
                        app:exitAnim="@anim/nav_default_exit_anim"
                        app:popEnterAnim="@anim/nav_default_pop_enter_anim"
                        app:popExitAnim="@anim/nav_default_pop_exit_anim"/>
            </fragment>
    
            <fragment android:id="@+id/b"
                      android:name="com.example.myapplication.FragmentB"
                      android:label="b"
                      tools:layout="@layout/b">
                <action android:id="@+id/action_b_to_a"
                        app:destination="@id/a"
                        app:enterAnim="@anim/nav_default_enter_anim"
                        app:exitAnim="@anim/nav_default_exit_anim"
                        app:popEnterAnim="@anim/nav_default_pop_enter_anim"
                        app:popExitAnim="@anim/nav_default_pop_exit_anim"
                        app:popUpTo="@+id/a"
                        app:popUpToInclusive="true"/>
            </fragment>
        </navigation>
        

    Quando o gráfico de navegação é aumentado, essas ações são analisadas, e os objetos NavAction correspondentes são gerados com as configurações definidas no gráfico. Por exemplo, action_b_to_a é definido como a navegação do destino b para o destino a. A ação inclui animações com o comportamento popTo que remove todos os destinos da pilha de retorno. Todas essas configurações são capturadas como NavOptions e anexadas a NavAction.

    Para acompanhar esse NavAction, use NavController.navigate(), passando o ID da ação, conforme mostrado no exemplo a seguir.

    Kotlin

        findNavController().navigate(R.id.action_b_to_a)
        

    Java

        Navigation.findNavController(this).navigate(R.id.action_b_to_a);
        

    Navegar usando URI

    Você pode usar navigate(Uri) para navegar diretamente para um destino de link direto implícito, conforme mostrado no exemplo a seguir.

    Kotlin

        val navController = findNavController()
        val deeplink = Uri.parse("android-app://androidx.navigation.app/profile")
        findNavController().navigate(deeplink)
        

    Java

        Uri deeplink = Uri.parse("android-app://androidx.navigation.app/profile");
        view.findNavController().navigate(deeplink);
        

    Ao contrário da navegação usando IDs de ação ou de destino, você pode navegar para qualquer URI no gráfico, independentemente de o destino estar visível ou não. Você pode navegar para um destino no gráfico atual ou para um destino em um gráfico completamente diferente.

    Ao navegar usando URI, a pilha de retorno não é redefinida. Esse comportamento é diferente de outras navegações de link direto, em que a pilha de retorno é substituída durante a navegação. No entanto, popUpTo e popUpToInclusive ainda removerão destinos da pilha de retorno como se você tivesse navegado usando um ID.

    Navegação e a pilha de retorno

    O Android mantém uma pilha de retorno que contém os destinos visitados. O primeiro destino do seu app é colocado na pilha quando o usuário abre o app. Cada chamada para o método navigate() coloca outro destino no topo da pilha. Tocar em Up ou Back chama os métodos NavController.navigateUp() e NavController.popBackStack(), respectivamente, para remover (ou retirar) o destino superior da pilha.

    NavController.popBackStack() retorna um valor booleano que indica se ele retornou para outro destino. O caso mais comum de retorno de false é quando você destaca manualmente o destino inicial do seu gráfico.

    Quando o método retorna false, NavController.getCurrentDestination() retorna null. Você é responsável por navegar para um novo destino ou por manipular o menu pop-up chamando finish() na sua atividade, conforme mostrado no exemplo a seguir.

    Kotlin

        ...
    
        if (!navController.popBackStack()) {
            // Call finish() on your Activity
            finish()
        }
    
        

    Java

        ...
    
        if (!navController.popBackStack()) {
            // Call finish() on your Activity
            finish();
        }
        

    popUpTo e popUpToInclusive

    Ao navegar usando uma ação, você também pode retirar destinos adicionais da pilha de retorno. Por exemplo, se o app tiver um fluxo de login inicial, assim que um usuário tiver feito login, todos os destinos relacionados ao login precisarão ser removidos da pilha de retorno para que o botão" "Voltar" não retorne os usuários ao fluxo de login.

    Para inserir destinos ao navegar de um destino para outro, adicione um atributo app:popUpTo ao elemento <action> associado. app:popUpTo instrui a biblioteca de navegação a remover alguns destinos da pilha de retorno como parte da chamada para navigate(). O valor do atributo é o ID do destino mais recente que precisa permanecer na pilha.

    Você também pode incluir app:popUpToInclusive="true" para indicar que o destino especificado em app:popUpTo também precisa ser removido da pilha de retorno.

    Exemplo de popUpTo: lógica circular

    Digamos que seu app tenha três destinos (A, B e C), juntamente com ações que levam de A a B, B a C e C de volta a A. O gráfico de navegação correspondente é mostrado na Figura 1:

    Figura 1. Um gráfico de navegação circular com três destinos: A, B e C.

    Em cada ação de navegação, um destino é adicionado à pilha de retorno. Se você navegasse várias vezes por esse fluxo, sua pilha de retorno conteria vários conjuntos de cada destino (A, B, C, A, B, C, A e assim por diante). Para evitar essa repetição, você pode especificar app:popUpTo e app:popUpToInclusive na ação que leva do destino C para o destino A, conforme mostrado no exemplo a seguir.

        <fragment
            android:id="@+id/c"
            android:name="com.example.myapplication.C"
            android:label="fragment_c"
            tools:layout="@layout/fragment_c">
    
            <action
                android:id="@+id/action_c_to_a"
                app:destination="@id/a"
                app:popUpTo="@+id/a"
                app:popUpToInclusive="true"/>
        </fragment>
        

    Depois de chegar ao destino C, a pilha de retorno contém uma instância de cada destino (A, B, C). Ao navegar de volta ao destino A, também popUpTo A, o que significa que removemos B e C da pilha ao navegar. Com app:popUpToInclusive="true", também retiramos primeiro A da pilha, apagando-o. Se você não usar app:popUpToInclusive, a pilha de retorno terá duas instâncias do destino A.