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
.