В вашей навигационной карте пункт назначения может представлять собой действие. Хотя лучшей практикой является использование одного действия в приложении, часто приложения используют отдельные действия для различных компонентов или экранов внутри приложения. В таких случаях пункты назначения в виде действий могут быть полезны.
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))
Java
startActivity(new Intent(context, DestinationActivity.class));
В некоторых случаях такой подход может быть неприемлем. Например, у вас может отсутствовать зависимость от класса Activity на этапе компиляции, или вы можете предпочесть уровень косвенности, обеспечиваемый неявным намерением. 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 :
Котлин
navController.navigate(
R.id.localDestinationActivity,
bundleOf("userId" to "someUser")
)
Java
Bundle args = new Bundle();
args.putString("userId", "someUser");
navController.navigate(R.id.localDestinationActivity, args);
В этом примере вместо {userId} используется someUser , и создается значение URI https://example.com?userId=someUser .