Места проведения мероприятий

В графе навигации пунктом назначения может быть действие. Хотя рекомендуется использовать в приложении только одно действие, часто для разных компонентов или экранов используются отдельные действия. В таких случаях могут быть полезны целевые страницы действий.

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.