Nel grafico di navigazione, una destinazione può essere un'attività. Anche se la best practice è avere una sola attività nell'app, spesso le app utilizzano attività separate per componenti o schermate distinti all'interno di un'app. Le destinazioni attività possono essere utili in questi casi.
Compose e Kotlin DSL
L'aggiunta di una destinazione di attività al grafico di navigazione è essenzialmente la stessa
sia in Compose sia quando si utilizza Kotlin DSL con i fragment. Questo perché
quando passi NavGraph al composable NavHost, utilizzi la stessa
lambda createGraph().
Per saperne di più, consulta Frammenti e Kotlin DSL.
XML
La creazione di una destinazione attività è simile alla creazione di una destinazione frammento. Tuttavia, la natura di una destinazione di attività è piuttosto diversa.
Per impostazione predefinita, la libreria di navigazione collega NavController a un layout
Activity e il grafico di navigazione attivo è limitato all'Activity attivo. Se un utente passa a un altro Activity, il grafico di navigazione
corrente non è più incluso nell'ambito. Ciò significa che una destinazione Activity
deve essere considerata un endpoint all'interno di un grafico di navigazione.
Per aggiungere una destinazione attività, specifica la destinazione Activity con il nome completo della classe:
<?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>
Questo XML equivale alla seguente chiamata a startActivity():
Kotlin
startActivity(Intent(context, DestinationActivity::class.java))
Java
startActivity(new Intent(context, DestinationActivity.class));
Potresti avere casi in cui questo approccio non è appropriato. Ad esempio, potresti non avere una dipendenza in fase di compilazione dalla classe di attività o potresti preferire il livello di indirezione di un intent implicito. Il
intent-filter nella voce del manifest per la destinazione Activity
determina la struttura della destinazione Activity.
Ad esempio, considera il seguente file manifest:
<?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>
La destinazione Activity corrispondente deve essere configurata con gli attributi
action e data corrispondenti a quelli della voce del manifest:
<?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>
Se specifichi targetPackage per l'attuale applicationId, l'ambito viene limitato
all'applicazione corrente, che include l'app principale.
Lo stesso meccanismo può essere utilizzato per i casi in cui vuoi che una specifica app sia la
destinazione. L'esempio seguente definisce una destinazione come un'app con un
applicationId di 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>
Argomenti dinamici
Gli esempi precedenti utilizzavano URL fissi per accedere alle destinazioni. Potresti
anche dover supportare URL dinamici in cui vengono inviate informazioni aggiuntive come parte dell'URL. Ad esempio, potresti inviare un ID utente in un URL con un formato simile a
https://example.com?userId=<actual user ID>.
In questo caso, utilizza dataPattern anziché l'attributo data.
Puoi quindi fornire argomenti da sostituire ai segnaposto denominati all'interno
del valore 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>
In questo esempio, puoi specificare un valore userId utilizzando Safe Args
o con un 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);
Questo esempio sostituisce someUser con {userId} e crea un valore URI di
https://example.com?userId=someUser.