وجهات الأنشطة

في مخطّط التنقّل، يمكن أن تكون الوجهة نشاطًا. على الرغم من أنّه من أفضل الممارسات استخدام نشاط واحد في تطبيقك، غالبًا ما تستخدم التطبيقات أنشطة منفصلة لمكوّنات أو شاشات مختلفة داخل التطبيق. ويمكن أن تكون وجهات النشاط مفيدة في مثل هذه الحالات.

Compose وKotlin DSL

إنّ إضافة وجهة نشاط إلى مخطّط التنقّل هي نفسها في Compose وعند استخدام Kotlin DSL مع أجزاء. يرجع ذلك إلى أنّه عند تمرير NavGraph إلى الدالة المركّبة NavHost، يمكنك استخدام تعبير lambda نفسه createGraph().

لمزيد من المعلومات، يُرجى الاطّلاع على مقالة الأجزاء وKotlin DSL.

تنسيق XML

يشبه إنشاء وجهة نشاط إنشاء وجهة جزء. ومع ذلك، يختلف نوع وجهة النشاط تمامًا.

تلقائيًا، تربط مكتبة Navigation السمة 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));

قد تكون هناك حالات لا يكون فيها هذا النهج مناسبًا. على سبيل المثال، قد لا يكون لديك تبعية في وقت التجميع على فئة النشاط، أو قد تفضّل مستوى التوجيه غير المباشر للانتقال من خلال implicit 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>.

في هذه الحالة، استخدِم 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.