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 o mesmo processo
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 mais informações, consulte Fragmentos e 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
.