アクティビティのデスティネーション

ナビゲーション グラフでは、デスティネーションがアクティビティである場合があります。1 つのアプリ内にアクティビティを 1 つだけ使用するのがベスト プラクティスですが、多くの場合、アプリではアプリ内の個別のコンポーネントまたは画面に別々のアクティビティを使用します。アクティビティのデスティネーションは、そのような場合に役立ちます。

Compose と Kotlin DSL

アクティビティ デスティネーションをナビゲーション グラフに追加する方法は、Compose の場合と、フラグメントで Kotlin DSL を使用する場合の両方で、基本的には同じです。これは、NavGraphNavHost コンポーザブルに渡すときに、同じ createGraph() ラムダを使用するためです。

詳細については、Kotlin DSL を使用してプログラムでグラフを作成するをご覧ください。

XML

アクティビティ デスティネーションの作成は、フラグメント デスティネーションの作成に似ています。ただし、アクティビティ デスティネーションの性質は大きく異なります。

デフォルトでは、Navigation ライブラリNavControllerActivity レイアウトにアタッチし、アクティブなナビゲーション グラフのスコープはアクティブな 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));

この方法が不適切である場合もあります。たとえば、アクティビティ クラスに対するコンパイル時の依存関係がない場合や、暗黙的インテントで移動するという一定のレベルの間接性が望ましい場合があります。デスティネーション Activity のマニフェスト エントリにある intent-filter によって、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 に指定すると、メインアプリを含む現在のアプリに限定されます。

特定のアプリをデスティネーションにするケースでは、同じメカニズムを使用できます。次の例では、デスティネーションが、com.example.android.another.app という applicationId のアプリとなるように定義しています。

<?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 をサポートする必要がある場合もあります。たとえば、https://example.com?userId=<actual user ID> のような形式の URL のユーザー 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>

この例では、Safe Args または Bundle を使用して userId 値を指定できます。

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);

この例では、{userId}someUser に置き換えて、https://example.com?userId=someUser の URI 値を作成しています。