สถานที่ทำกิจกรรม

ในกราฟการนำทาง ปลายทางอาจเป็นกิจกรรม แม้ว่าการมีกิจกรรมเดียวในแอปจะเป็นแนวทางปฏิบัติแนะนำ แต่แอปมักจะใช้กิจกรรมที่แยกกันสำหรับคอมโพเนนต์หรือหน้าจอที่แตกต่างกันภายในแอป ซึ่งในกรณีดังกล่าว ปลายทางของกิจกรรมอาจมีประโยชน์

Compose และ Kotlin DSL

การเพิ่มปลายทางของกิจกรรมลงในกราฟการนำทางนั้นโดยพื้นฐานแล้วจะเหมือนกันทั้งใน Compose และเมื่อใช้ Kotlin DSL กับ Fragment เนื่องจากเมื่อส่ง NavGraph ไปยัง NavHost ที่ใช้ได้ คุณจะใช้แลมบ์ดา createGraph() เดียวกัน

ดูข้อมูลเพิ่มเติมได้ที่ Fragment และ Kotlin DSL

XML

การสร้างปลายทางของ กิจกรรม จะคล้ายกับการสร้างปลายทางของ Fragment อย่างไรก็ตาม ลักษณะของปลายทางของกิจกรรมนั้นค่อนข้างแตกต่างกัน

โดยค่าเริ่มต้น ไลบรารีการนำทางจะแนบ 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));

คุณอาจพบกรณีที่วิธีนี้ไม่เหมาะสม เช่น คุณอาจไม่มีทรัพยากร Dependency ในเวลาคอมไพล์กับคลาสกิจกรรม หรืออาจต้องการระดับการอ้างอิงทางอ้อมในการใช้ Intent แบบไม่เจาะจงปลายทาง intent-filter ในรายการ Manifest สำหรับปลายทาง Activity จะเป็นตัวกำหนดวิธีที่คุณต้องจัดโครงสร้างปลายทาง Activity

ตัวอย่างเช่น ลองพิจารณาไฟล์ 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>

ปลายทาง Activity ที่เกี่ยวข้องต้องได้รับการกำหนดค่าด้วย action และ data ที่ตรงกับแอตทริบิวต์ในรายการ 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>

การระบุ 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>

ในกรณีนี้ ให้ใช้ dataPattern แทนแอตทริบิวต์ data จากนั้นคุณสามารถระบุอาร์กิวเมนต์ที่จะใช้แทนตัวยึดตำแหน่งที่มีชื่อภายในค่า 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