В графе навигации пунктом назначения может быть действие. Хотя рекомендуется использовать в приложении только одно действие, часто для разных компонентов или экранов используются отдельные действия. В таких случаях могут быть полезны целевые страницы действий.
Compose и Kotlin DSL
Добавление пункта назначения в граф навигации выполняется одинаково как в Compose, так и при использовании Kotlin DSL с фрагментами. Это связано с тем, что при передаче NavGraph в composable-функцию NavHost вы используете ту же лямбду createGraph().
Дополнительную информацию см. в статье Фрагменты и Kotlin DSL.
XML
Создание пункта назначения activity похоже на создание пункта назначения fragment. Однако пункты назначения для занятий сильно отличаются.
По умолчанию библиотека 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));
Однако в некоторых случаях такой подход может быть нецелесообразен. Например, у вас может не быть зависимости времени компиляции от класса действия или вы предпочитаете уровень косвенности, который обеспечивается неявным намерением. 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>.
В этом случае вместо атрибута 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:
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.