در نمودار ناوبری شما، یک مقصد میتواند یک فعالیت باشد. اگرچه بهترین روش این است که یک فعالیت واحد در برنامه خود داشته باشید، اما برنامهها اغلب از فعالیتهای جداگانه برای اجزای مجزا یا صفحه نمایش در یک برنامه استفاده میکنند. مقاصد فعالیت میتوانند در چنین مواردی مفید باشند.
نوشتن و کاتلین DSL
افزودن یک مقصد فعالیت به گراف ناوبری شما اساساً هم در Compose و هم هنگام استفاده از Kotlin DSL با fragments یکسان است. دلیل این امر این است که هنگام ارسال NavGraph خود به NavHost composable، از همان لامبدا createGraph() استفاده میکنید.
برای اطلاعات بیشتر، به بخش Fragments و 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));
ممکن است مواردی داشته باشید که این رویکرد مناسب نباشد. برای مثال، ممکن است وابستگی زمان کامپایل به کلاس activity نداشته باشید، یا ممکن است سطح غیرمستقیم بودنِ عبور از یک intent ضمنی را ترجیح دهید. intent-filter در ورودی manifest برای 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 استفاده کنید. سپس میتوانید آرگومانهایی را برای جایگزینی با متغیرهای نامگذاری شده در مقدار 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 مشخص کنید:
کاتلین
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 ایجاد میکند.