Criar destinos

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

Criar um destino a partir de um fragmento ou uma atividade já existente

No Navigation Editor, se você tiver um tipo de destino que queira adicionar ao seu gráfico de navegação, clique em New Destination e, em seguida, clique no destino correspondente no menu suspenso exibido. Agora você pode ter uma prévia do destino na visualização Design junto com o XML correspondente na visualização Text do seu gráfico de navegação.

Criar um novo destino de fragmento

Para adicionar um novo tipo de 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 1 mostra um exemplo de destino e um destino de marcador.

Figura 1. Um destino e um marcador

Criar um destino usando um DialogFragment

Se você já tem um DialogFragment, use o elemento <dialog> para adicionar a caixa de diálogo ao seu gráfico de navegação, conforme mostrado no exemplo a seguir:

<?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">

...

<dialog
    android:id="@+id/my_dialog_fragment"
    android:name="androidx.navigation.myapp.MyDialogFragment">
    <argument android:name="myarg" android:defaultValue="@null" />
        <action
            android:id="@+id/myaction"
            app:destination="@+id/another_destination"/>
</dialog>

...

</navigation>

Criar um novo destino de atividade

A criação de um destino Activity é semelhante à criação de um destino Fragment. No entanto, a natureza de um destino Activity é muito diferente.

Por padrão, a biblioteca Navigation anexa o NavController a um layout de Activity, e o gráfico de navegação ativo tem o escopo na Activity ativa. Se um usuário navegar para uma Activity diferente, o gráfico de navegação atual não estará mais no escopo. Isso significa que um destino Activity precisa ser considerado um endpoint em um gráfico de navegação.

Para adicionar um destino Activity, especifique o destino Activity com o nome da classe totalmente qualificado:

<?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/navigation_graph"
    app:startDestination="@id/simpleFragment">

    <activity
        android:id="@+id/sampleActivityDestination"
        android:name="com.example.android.navigation.activity.DestinationActivity"
        android:label="@string/sampleActivityTitle" />
</navigation>

Esse XML é equivalente à chamada para startActivity() a seguir:

Kotlin

startActivity(Intent(context, DestinationActivity::class.java))

Java

startActivity(new Intent(context, DestinationActivity.class));

Pode haver casos em que essa abordagem não é adequada. Por exemplo, você pode não ter uma dependência de tempo de compilação na classe de atividade ou pode preferir o nível de indireção de uma intent implícita. A intent-filter na entrada do manifesto da Activity determina como você precisa estruturar o destino da Activity.

Por exemplo, considere o arquivo de manifesto a seguir:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.android.navigation.activity">
    <application>
        <activity android:name=".DestinationActivity">
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <data
                    android:host="example.com"
                    android:scheme="https" />
                <category android:name="android.intent.category.BROWSABLE" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
    </application>
</manifest>

O destino Activity correspondente precisa ser configurado com os atributos action e data correspondentes a eles na entrada do manifesto:

<?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/navigation_graph"
    app:startDestination="@id/simpleFragment">
    <activity
        android:id="@+id/localDestinationActivity"
        android:label="@string/localActivityTitle"
        app:action="android.intent.action.VIEW"
        app:data="https://example.com"
        app:targetPackage="${applicationId}" />
</navigation>

Especificar o targetPackage para o applicationId atual limita o escopo ao aplicativo atual, que inclui a instância principal do app.

O mesmo mecanismo pode ser usado para casos em que você queira que um app específico seja o destino. O exemplo a seguir define um destino como um app com um applicationId de com.example.android.another.app.

<?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/navigation_graph"
    app:startDestination="@id/simpleFragment">
    <activity
        android:id="@+id/localDestinationActivity"
        android:label="@string/localActivityTitle"
        app:action="android.intent.action.VIEW"
        app:data="https://example.com"
        app:targetPackage="com.example.android.another.app" />
</navigation>

Argumentos dinâmicos

Os exemplos anteriores usavam URLs fixos para navegar até os destinos. Talvez também seja necessário oferecer suporte a URLs dinâmicos em que mais informações são enviadas como parte do URL. Por exemplo, é possível enviar um ID do usuário em um URL com um formato semelhante a https://example.com?userId=<actual user ID>.

Nesse caso, em vez do atributo data, use dataPattern. É possível fornecer argumentos a serem substituídos por marcadores nomeados no valor dataPattern:

<?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/navigation_graph"
    app:startDestination="@id/simpleFragment">
    <activity
        android:id="@+id/localDestinationActivity"
        android:label="@string/localActivityTitle"
        app:action="android.intent.action.VIEW"
        app:dataPattern="https://example.com?userId={userId}"
        app:targetPackage="com.example.android.another.app">
        <argument
            android:name="userId"
            app:argType="string" />
    </activity>
</navigation>

Neste exemplo, é possível especificar um valor userId usando o Safe Args ou com um Bundle:

Kotlin

navController.navigate(
    R.id.localDestinationActivity,
    bundleOf("userId" to "someUser")
)

Java

Bundle args = new Bundle();
args.putString("userId", "someUser");
navController.navigate(R.id.localDestinationActivity, args);

Este exemplo substitui someUser por {userId} e cria um valor de URI de https://example.com?userId=someUser.

Destinos de marcador

Você pode usar marcadores para representar destinos não implementados. Um marcador serve como uma representação visual de um destino. No Navigation Editor, você pode usar marcadores como faria com qualquer outro destino.