Começar a usar o componente de navegação

Este tópico mostra como configurar e trabalhar com o componente Navigation. Para ter uma visão geral de alto nível do componente de navegação, consulte Visão geral da navegação.

Configurar o ambiente

Para incluir suporte à navegação no seu projeto, adicione as dependências abaixo ao arquivo build.gradle do seu app:

Groovy

dependencies {
  def nav_version = "2.5.3"

  // Java language implementation
  implementation "androidx.navigation:navigation-fragment:$nav_version"
  implementation "androidx.navigation:navigation-ui:$nav_version"

  // Kotlin
  implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
  implementation "androidx.navigation:navigation-ui-ktx:$nav_version"

  // Feature module Support
  implementation "androidx.navigation:navigation-dynamic-features-fragment:$nav_version"

  // Testing Navigation
  androidTestImplementation "androidx.navigation:navigation-testing:$nav_version"

  // Jetpack Compose Integration
  implementation "androidx.navigation:navigation-compose:$nav_version"
}

Kotlin

dependencies {
  val nav_version = "2.5.3"

  // Java language implementation
  implementation("androidx.navigation:navigation-fragment:$nav_version")
  implementation("androidx.navigation:navigation-ui:$nav_version")

  // Kotlin
  implementation("androidx.navigation:navigation-fragment-ktx:$nav_version")
  implementation("androidx.navigation:navigation-ui-ktx:$nav_version")

  // Feature module Support
  implementation("androidx.navigation:navigation-dynamic-features-fragment:$nav_version")

  // Testing Navigation
  androidTestImplementation("androidx.navigation:navigation-testing:$nav_version")

  // Jetpack Compose Integration
  implementation("androidx.navigation:navigation-compose:$nav_version")
}

Para ver informações sobre como adicionar outros componentes de arquitetura ao seu projeto, consulte Como adicionar componentes ao seu projeto.

Criar um gráfico de navegação

A navegação ocorre entre os destinos do app, ou seja, em qualquer lugar no app em que os usuários possam navegar. Esses destinos são conectados por ações.

Um gráfico de navegação é um arquivo de recursos que contém todos os seus destinos e ações. O gráfico representa todos os caminhos de navegação do seu app.

A Figura 1 mostra uma representação visual de um gráfico de navegação para um app de exemplo que contém seis destinos conectados por cinco ações. Cada destino é representado por uma miniatura de visualização, e as ações de conexão são representadas por setas que mostram como os usuários podem navegar de um destino para outro.

Figura 1. Um gráfico de navegação que mostra visualizações de seis destinos diferentes conectados por meio de cinco ações.
  1. Destinos são as diferentes áreas de conteúdo do seu app.
  2. Ações são conexões lógicas entre seus destinos que representam os caminhos que os usuários podem seguir.

Para adicionar um gráfico de navegação ao projeto, faça o seguinte:

  1. Na janela "Project", clique com o botão direito do mouse no diretório res e selecione New > Android Resource File. A caixa de diálogo New Resource File é exibida.
  2. Digite um nome no campo File name, por exemplo, "nav_graph".
  3. Selecione Navigation na lista suspensa Resource type e clique em OK.

Quando você adicionar seu primeiro gráfico de navegação, o Android Studio criará um diretório de recursos navigation dentro do diretório res. Esse diretório contém seu arquivo de recurso de gráfico de navegação (nav_graph.xml, por exemplo).

Depois de adicionar um gráfico, o Android Studio abre o gráfico no Navigation Editor. No Navigation Editor, você pode editar visualmente os gráficos de navegação ou editar diretamente o XML subjacente.

Figura 2. O Navigation Editor
  1. Painel Destinations: lista seu host de navegação e todos os destinos atualmente no Graph Editor.
  2. Graph Editor: contém uma representação visual do seu gráfico de navegação. Você pode alternar entre a visualização Design e a representação XML subjacente na visualização Text.
  3. Attributes: mostra atributos para o item selecionado no momento no gráfico de navegação.

Clique na guia Text para ver o XML correspondente, que precisa ser semelhante ao seguinte snippet:

<?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"
            android:id="@+id/nav_graph">

</navigation>

<navigation> é o elemento raiz de um gráfico de navegação. Conforme você adiciona destinos e conecta ações ao gráfico, é possível ver os elementos <destination> e <action> correspondentes aqui como elementos filhos. Se você tiver gráficos aninhados, eles aparecerão como elementos filhos <navigation>.

Adicionar um NavHost a uma atividade

Uma das partes principais do componente de navegação é o host de navegação. O host de navegação é um contêiner vazio em que os destinos são trocados enquanto o usuário navega pelo seu app.

Um host de navegação precisa derivar de NavHost. A implementação NavHost padrão do componente de navegação, NavHostFragment, gerencia a troca de destinos de fragmento.

Adicionar um NavHostFragment via XML

O XML de exemplo abaixo mostra um NavHostFragment como parte da atividade principal de um app.

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <androidx.appcompat.widget.Toolbar
        .../>

    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"

        app:defaultNavHost="true"
        app:navGraph="@navigation/nav_graph" />

    <com.google.android.material.bottomnavigation.BottomNavigationView
        .../>

</androidx.constraintlayout.widget.ConstraintLayout>

Observe o seguinte:

  • O atributo android:name contém o nome da classe da implementação de NavHost.
  • O atributo app:navGraph associa o NavHostFragment a um gráfico de navegação. O gráfico de navegação especifica todos os destinos nesse NavHostFragment para onde os usuários podem navegar.
  • O atributo app:defaultNavHost="true" garante que o NavHostFragment intercepte o botão "Voltar" do sistema. Observe que apenas um NavHost pode ser o padrão. Se você tem vários hosts no mesmo layout (como em layouts de dois painéis), especifique apenas um NavHost padrão.

Você também pode usar o Layout Editor para adicionar um NavHostFragment a uma atividade fazendo o seguinte:

  1. Na lista de arquivos de projeto, clique duas vezes no arquivo XML de layout da sua atividade para abri-lo no Layout Editor.
  2. No painel Palette, escolha a categoria Containers ou, como alternativa, procure por "NavHostFragment".
  3. Arraste a visualização NavHostFragment até sua atividade.
  4. Em seguida, na caixa de diálogo Navigation Graphs exibida, escolha o gráfico de navegação correspondente a ser associado a esse NavHostFragment e clique em OK.

Adicionar destinos ao gráfico de navegação

Você pode criar um destino a partir de um fragmento ou uma atividade existente. Também é possível usar o Navigation Editor para criar um novo destino ou criar um marcador para depois substituir por um fragmento ou uma atividade.

Neste exemplo, vamos criar um novo destino. Para adicionar um novo destino usando o Navigation Editor, faça o seguinte:

  1. No Navigation Editor, clique no ícone New Destination e, em seguida, clique em Create new destination.
  2. Na caixa de diálogo New Android Component exibida, crie seu fragmento. Para saber mais sobre fragmentos, consulte a documentação do fragmento.

De volta ao Navigation Editor, observe que o Android Studio adicionou esse destino ao gráfico.

A Figura 3 mostra um exemplo de um destino e um destino de marcador.

Figura 3. Um destino e um marcador.

Para ver outras formas de adicionar destinos ao seu gráfico de navegação, consulte Criar destinos.

Anatomia de um destino

Clique em um destino para selecioná-lo e observe os seguintes atributos no painel Attributes:

  • O campo Type indica se o destino é implementado como um fragmento, uma atividade ou outra classe personalizada no código-fonte.
  • O campo Label contém o nome legível pelo usuário para o destino. Isso pode ser exibido na IU, por exemplo, se você conectar o NavGraph a uma Toolbar usando setupWithNavController(). Por isso, é recomendável usar strings de recursos para esse valor.
  • O campo ID contém o ID do destino que é usado para referenciar o destino no código.
  • O menu suspenso Class mostra o nome da classe associada ao destino. Você pode clicar nessa lista suspensa para alterar a classe associada para outro tipo de destino.

Clique na guia Text para exibir a visualização XML do seu gráfico de navegação. O XML contém os mesmos atributos id, name, label e layout do destino, como mostrado abaixo.

<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:android="http://schemas.android.com/apk/res/android"
    app:startDestination="@id/blankFragment">
    <fragment
        android:id="@+id/blankFragment"
        android:name="com.example.cashdog.cashdog.BlankFragment"
        android:label="@string/label_blank"
        tools:layout="@layout/fragment_blank" />
</navigation>

Designar uma tela como destino inicial

O destino inicial é a primeira tela que os usuários encontram ao abrir seu app e é a última que eles encontram quando saem do app. O Navigation Editor usa um ícone de casa para indicar o destino inicial.

Depois de definir todos os seus destinos, você pode escolher um destino inicial fazendo o seguinte:

  1. Na guia Design, clique no destino para destacá-lo.

  2. Clique no botão Assign start destination . Como alternativa, você pode clicar com o botão direito no destino e clicar em Set as Start Destination.

Conectar destinos

Uma ação é uma conexão lógica entre destinos. As ações são representadas como setas no gráfico de navegação. As ações geralmente conectam um destino ao outro, embora você também possa criar ações globais que levam a um destino específico partindo de qualquer lugar no app.

Com as ações, você representa os diferentes caminhos que os usuários podem seguir no app. Para navegar até os destinos, você ainda precisa criar o código para executar a navegação. Isso é abordado na seção Navegar até um destino posteriormente neste tópico.

Você pode usar o Navigation Editor para conectar dois destinos fazendo o seguinte:

  1. Na guia Design, passe o mouse sobre o lado direito do destino a partir do qual você quer que os usuários naveguem. Um círculo aparecerá sobre o lado direito do destino, como mostrado na Figura 4.

    Figura 4. Um destino com um círculo de conexão de ação
  2. Clique o cursor sobre o destino ao qual você quer que os usuários naveguem, arraste e solte. A linha resultante entre os dois destinos representa uma ação, conforme mostrado na Figura 5.

    Figura 5. Como conectar destinos a uma ação
  3. Clique na seta para destacar a ação. Os seguintes atributos aparecem no painel Attributes:

    • O campo Type contém "Action".
    • O campo ID contém o ID da ação.
    • O campo Destination contém o ID do fragmento ou da atividade do destino.
  4. Clique na guia Text para alternar para a visualização XML. Agora, um elemento de ação é adicionado ao destino de origem. A ação tem um ID e um atributo de destino que contém o ID do próximo destino, como mostrado no exemplo abaixo.

    <?xml version="1.0" encoding="utf-8"?>
    <navigation xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:android="http://schemas.android.com/apk/res/android"
        app:startDestination="@id/blankFragment">
        <fragment
            android:id="@+id/blankFragment"
            android:name="com.example.cashdog.cashdog.BlankFragment"
            android:label="@string/label_blank"
            tools:layout="@layout/fragment_blank" >
            <action
                android:id="@+id/action_blankFragment_to_blankFragment2"
                app:destination="@id/blankFragment2" />
        </fragment>
        <fragment
            android:id="@+id/blankFragment2"
            android:name="com.example.cashdog.cashdog.BlankFragment2"
            android:label="@string/label_blank_2"
            tools:layout="@layout/fragment_blank_fragment2" />
    </navigation>
    

No gráfico de navegação, as ações são representadas por elementos <action>. No mínimo, uma ação contém o respectivo ID e o ID do destino ao qual um usuário deve ser levado.

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. Você pode recuperar um NavController usando um dos seguintes métodos:

Kotlin:

Java:

Ao criar o NavHostFragment usando FragmentContainerView ou se você adicionar manualmente o NavHostFragment à sua atividade usando um FragmentTransaction, a tentativa de recuperação do NavController no onCreate() de uma atividade com Navigation.findNavController(Activity, @IdRes int) falhará. Você precisa recuperar NavController diretamente de NavHostFragment.

Kotlin

val navHostFragment =
        supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
val navController = navHostFragment.navController

Java

NavHostFragment navHostFragment =
        (NavHostFragment) getSupportFragmentManager().findFragmentById(R.id.nav_host_fragment);
NavController navController = navHostFragment.getNavController();

Garantir a segurança de tipos usando Safe Args

A maneira recomendada de navegar entre destinos é usar o plug-in Safe Args do Gradle. Esse plug-in gera classes de builders e objetos simples que permitem a transmissão de argumentos e navegação de tipos seguros entre destinos.

Para adicionar Safe Args ao seu projeto, inclua o seguinte classpath no seu arquivo build.gradle de nível superior:

Groovy

buildscript {
    repositories {
        google()
    }
    dependencies {
        def nav_version = "2.5.3"
        classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version"
    }
}

Kotlin

buildscript {
    repositories {
        google()
    }
    dependencies {
        val nav_version = "2.5.3"
        classpath("androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version")
    }
}

Você também precisa aplicar um dos dois plug-ins disponíveis.

Para gerar um código de linguagem Java adequado para módulos Java ou Java e Kotlin mistos, adicione esta linha ao arquivo build.gradle do seu app ou módulo:

Groovy

plugins {
  id 'androidx.navigation.safeargs'
}

Kotlin

plugins {
    id("androidx.navigation.safeargs")
}

Como alternativa, para gerar o código Kotlin adequado para módulos somente Kotlin, adicione:

Groovy

plugins {
  id 'androidx.navigation.safeargs.kotlin'
}

Kotlin

plugins {
    id("androidx.navigation.safeargs.kotlin")
}

Você precisa ter android.useAndroidX=true no arquivo gradle.properties, como mostrado em Migrar para o AndroidX.

Depois que o plug-in Safe Args é ativado, ele gera um código que contém classes e métodos para cada ação que você definiu. Para cada ação, o Safe Args também gerará uma classe para cada destino de origem, que é o destino de origem da ação. O nome da classe gerada é uma combinação do nome da classe de destino de origem e da palavra "Directions". Por exemplo, se o destino tem o nome de SpecifyAmountFragment, a classe gerada terá o nome SpecifyAmountFragmentDirections. A classe gerada contém um método estático para cada ação definida no destino de origem. Esse método usa todos os parâmetros de ação definidos como argumentos e retorna um objeto NavDirections que você pode transmitir para navigate().

Como exemplo, vamos supor que temos um gráfico de navegação com uma única ação que conecta o destino de origem, SpecifyAmountFragment, a um destino de recebimento, ConfirmationFragment.

O Safe Args gera uma classe SpecifyAmountFragmentDirections com um único método, actionSpecifyAmountFragmentToConfirmationFragment(), que retorna um objeto NavDirections. Esse objeto NavDirections retornado pode ser transmitido diretamente para navigate(), como mostrado no exemplo a seguir.

Kotlin

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

Java

@Override
public void onClick(View view) {
    NavDirections action =
        SpecifyAmountFragmentDirections
            .actionSpecifyAmountFragmentToConfirmationFragment();
    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.

Mais informações

Se você encontrar problemas com o Navigation, envie um feedback por um dos seguintes canais:

Para saber como fornecer as informações mais úteis nos relatórios de bugs, consulte os seguintes links: