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 distintos dentro do app. Os destinos da atividade podem ser úteis nesses casos.

DSL do Compose e do Kotlin

A adição de um destino de atividade ao gráfico de navegação é essencialmente a mesma 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 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 Activity, e o gráfico de navegação ativo tem o escopo definido para o Activity ativo. Se um usuário navegar para um 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 à seguinte chamada para startActivity():

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, talvez você não tenha 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 para o destino Activity determina como você precisa estruturar o destino 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 aos da 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 targetPackage como o applicationId atual limita o escopo ao aplicativo atual, que inclui o app principal.

O mesmo mecanismo pode ser usado para casos em que você quer 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 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, você pode 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.