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