Destinos de atividade

No gráfico de navegação, um destino pode ser uma atividade. Embora seja uma prática recomendada ter uma única atividade no app, os apps geralmente usam atividades separadas para componentes ou telas diferentes. Os destinos de atividade podem ser úteis nesses casos.

DSL do Compose e do Kotlin

Adicionar um destino de atividade ao gráfico de navegação é essencialmente a mesma coisa no Compose e ao usar a DSL do Kotlin com fragmentos. Isso ocorre porque ao transmitir o NavGraph para o elemento combinável NavHost, você usa a mesma lambda createGraph().

Para saber mais, consulte Criar um gráfico de maneira programática usando a DSL do Kotlin.

XML

A criação de um destino de atividade é semelhante à criação de um destino de fragmento. No entanto, a natureza de um destino de atividade é 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 definido para a 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 de atividade, 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() abaixo:

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. O intent-filter na entrada do manifesto da Activity determina como você precisa estruturar o destino da Activity.

Por exemplo, considere o arquivo de manifesto abaixo:

<?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 abaixo 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 de posição 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.