Na wykresie nawigacyjnym miejsce docelowe może być aktywnością. Chociaż najlepiej mieć jedną aktywność w aplikacji, aplikacje często używają osobnych aktywności dla różnych komponentów lub ekranów w aplikacji. W takich przypadkach przydają się miejsca docelowe aktywności.
Compose i Kotlin DSL
Dodawanie miejsca docelowego aktywności do wykresu nawigacyjnego działa zasadniczo tak samo w przypadku tworzenia i używania DSL Kotlin z fragmentami. Dzieje się tak, ponieważ podczas przekazywania właściwości NavGraph
do funkcji kompozycyjnej NavHost
używasz tej samej funkcji lambda createGraph()
.
Więcej informacji znajdziesz w artykule Automatyczne tworzenie wykresu za pomocą języka DSL Kotlin.
Plik XML
Tworzenie miejsca docelowego aktywności przypomina tworzenie miejsca docelowego fragmentu. Charakter miejsca docelowego aktywności jest jednak zupełnie inny.
Domyślnie biblioteka nawigacji dołącza element NavController
do układu Activity
, a aktywny wykres nawigacyjny jest ograniczony do aktywnego obszaru Activity
. Jeśli użytkownik przejdzie pod inny element (Activity
), bieżący wykres nawigacyjny przestanie być uwzględniony w zakresie. Oznacza to, że miejsce docelowe Activity
powinno być traktowane jako punkt końcowy na wykresie nawigacyjnym.
Aby dodać miejsce docelowe aktywności, określ miejsce docelowe Activity
za pomocą jego pełnej i jednoznacznej nazwy klasy:
<?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>
Ten kod XML jest odpowiednikiem następującego wywołania funkcji startActivity()
:
Kotlin
startActivity(Intent(context, DestinationActivity::class.java))
Java
startActivity(new Intent(context, DestinationActivity.class));
W niektórych przypadkach takie podejście może być nieodpowiednie. Możesz na przykład nie mieć uzależnionej od klasy działania zależności czasu kompilacji lub ustawić poziom pośredni, który polega na przekazywaniu intencji pośredniej. Element intent-filter
w wpisie o miejscu docelowym Activity
w pliku manifestu określa strukturę miejsca docelowego Activity
.
Przeanalizujmy na przykład ten plik manifestu:
<?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>
Odpowiednie miejsce docelowe Activity
musi być skonfigurowane za pomocą atrybutów action
i data
pasujących do tych we wpisie manifestu:
<?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>
Ustawienie zakresu targetPackage
na bieżącą aplikację applicationId
ogranicza zakres do bieżącej aplikacji, w tym aplikacji głównej.
Tego samego mechanizmu możesz używać w przypadkach, gdy stroną docelową ma być konkretna aplikacja. Ten przykład określa miejsce docelowe jako aplikację z właściwością applicationId
o wartości 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>
Argumenty dynamiczne
W poprzednich przykładach do przechodzenia do miejsc docelowych używano stałych adresów URL. Może być też konieczna obsługa dynamicznych adresów URL, w których w ramach adresu URL przesyłane są dodatkowe informacje. Identyfikator użytkownika możesz na przykład wysyłać w adresie URL w formacie podobnym do https://example.com?userId=<actual user ID>
.
W takim przypadku zamiast atrybutu data
użyj dataPattern
.
Następnie możesz podać argumenty, które zostaną zastąpione nazwanymi symbolami zastępczymi w wartości 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>
W tym przykładzie możesz określić wartość userId
za pomocą Safe Args lub 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);
W tym przykładzie zastępuje się someUser
wartością {userId}
i tworzy wartość identyfikatora URI https://example.com?userId=someUser
.