יעדי הפעילות

בגרף הניווט, יעד יכול להיות פעילות. מומלץ להשתמש בפעילות אחת באפליקציה, אבל לעיתים קרובות אפליקציות משתמשות בפעילויות נפרדות לרכיבים או למסכים שונים באפליקציה. במקרים כאלה, יעדי פעילות יכולים להיות שימושיים.

‫Compose ו-Kotlin DSL

הוספת יעד פעילות לתרשים הניווט היא זהה גם ב-Compose וגם כשמשתמשים ב-Kotlin DSL עם פרגמנטים. הסיבה לכך היא שכאשר מעבירים את NavGraph אל רכיב ה-NavHost, משתמשים באותו createGraph() lambda.

מידע נוסף זמין במאמר בנושא Fragments and the Kotlin DSL.

XML

יצירת יעד מסוג פעילות דומה ליצירת יעד מסוג קטע. עם זאת, אופי היעד של פעילות שונה למדי.

כברירת מחדל, ספריית הניווט מצרפת את NavController לפריסת Activity, וגרף הניווט הפעיל מוגבל ל-Activity הפעיל. אם משתמש מנווט לActivity אחר, גרף הניווט הנוכחי כבר לא בתחום. המשמעות היא שיעד Activity צריך להיחשב כנקודת קצה בגרף ניווט.

כדי להוסיף יעד לפעילות, מציינים את היעד Activity עם שם המחלקה המלא שלו:

<?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>

ה-XML הזה שקול לקריאה הבאה ל-startActivity():

Kotlin

startActivity(Intent(context, DestinationActivity::class.java))

Java

startActivity(new Intent(context, DestinationActivity.class));

יכול להיות שיהיו מקרים שבהם הגישה הזו לא תתאים. לדוגמה, יכול להיות שאין לכם תלות בזמן קומפילציה במחלקת הפעילות, או שאתם מעדיפים את רמת ההפניה העקיפה של מעבר דרך אובייקט Intent מרומז. הערך intent-filter ברשומה של היעד Activity בקובץ המניפסט קובע את המבנה של היעד Activity.

לדוגמה, קובץ המניפסט הבא:

<?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>

צריך להגדיר את יעד Activity המתאים עם המאפיינים action ו-data שזהים למאפיינים שמופיעים ברשומה במניפסט:

<?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>

אם מציינים targetPackage ל-applicationId הנוכחי, ההיקף מוגבל לאפליקציה הנוכחית, כולל האפליקציה הראשית.

אפשר להשתמש באותו מנגנון במקרים שבהם רוצים שאפליקציה ספציפית תהיה היעד. בדוגמה הבאה מוגדר יעד שהוא אפליקציה עם applicationId של 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>

ארגומנטים דינמיים

בדוגמאות הקודמות השתמשנו בכתובות URL קבועות כדי לנווט ליעדים. יכול להיות שתצטרכו לתמוך גם בכתובות URL דינמיות שבהן מידע נוסף נשלח כחלק מכתובת ה-URL. לדוגמה, יכול להיות שאתם שולחים מזהה משתמש בכתובת URL בפורמט שדומה ל-https://example.com?userId=<actual user ID>.

במקרה כזה, במקום המאפיין data, צריך להשתמש במאפיין dataPattern. אחר כך תוכלו לספק ארגומנטים שיוחלפו ב-placeholders עם שמות בתוך הערך 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>

בדוגמה הזו, אפשר לציין ערך userId באמצעות Safe Args או באמצעות 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);

בדוגמה הזו, המחרוזת someUser מוחלפת במחרוזת {userId} ונוצר ערך URI של https://example.com?userId=someUser.