В вашем навигационном графике пункт назначения может быть действием. Хотя лучше всего иметь в приложении одно действие, приложения часто используют отдельные действия для отдельных компонентов или экрана внутри приложения. В таких случаях могут быть полезны направления деятельности.
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))
Ява
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
:
Котлин
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
.