مقصدهای فعالیت

در نمودار پیمایش شما، مقصد می‌تواند یک فعالیت باشد. درحالی‌که بهترین روال این است که یک فعالیت در برنامه‌تان داشته باشید، برنامه‌ها اغلب از فعالیت‌های جداگانه برای مؤلفه‌ها یا صفحه‌های متمایز در برنامه استفاده می‌کنند. در چنین مواردی، مقصدهای فعالیت می‌توانند مفید باشند.

Compose و Kotlin DSL

افزودن مقصد فعالیت به نمودار پیمایش اساساً در هر دو Compose و هنگام استفاده از Kotlin DSL با قطعه‌ها یکسان است. دلیلش این است که هنگام ارسال NavGraph به NavHost قابل‌ترکیب، از همان createGraph() لامبدا استفاده می‌کنید.

برای اطلاعات بیشتر، قطعات و 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() است:

کاتلین

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

جاوا

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

ممکن است مواردی وجود داشته باشد که این رویکرد مناسب نباشد. برای مثال، ممکن است وابستگی زمان ترجمه به کلاس فعالیت نداشته باشید، یا ممکن است سطح غیرمستقیم رفتن ازطریق قصد ضمنی را ترجیح دهید. 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>

متغیرهای مستقل پویا

نمونه‌های قبلی از نشانی‌های وب ثابت برای پیمایش به مقصدها استفاده می‌کردند. همچنین ممکن است لازم باشد از نشانی‌های وب پویا که اطلاعات اضافی به‌عنوان بخشی از نشانی وب ارسال می‌شود پشتیبانی کنید. برای مثال، ممکن است شناسه کاربر را در نشانی وبی با قالبی مشابه https://example.com?userId=<actual user ID> ارسال کنید.

در این حالت، به‌جای مشخصه data، از dataPattern استفاده کنید. سپس می‌توانید آرگومان‌هایی را برای جایگزینی با جای‌بان‌های نام‌گذاری‌شده در مقدار 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 را بااستفاده از آرگومان‌های ایمن یا با Bundle مشخص کنید:

کاتلین

navController.navigate(
    R.id.localDestinationActivity,
    bundleOf("userId" to "someUser")
)

جاوا

Bundle args = new Bundle();
args.putString("userId", "someUser");
navController.navigate(R.id.localDestinationActivity, args);

این مثال someUser را جایگزین {userId} می‌کند و مقدار URI https://example.com?userId=someUser را ایجاد می‌کند.