NavEntryDecorator クラスを使用すると、追加情報を提供したり、同じロジックをリンク先に適用したりできます。このクラスは、バックスタック内の各 NavEntry をコンポーザブル関数でラップします。つまり、エントリのコンテンツを装飾します。
カスタム デコレータを作成する
デコレータを作成するには、NavEntryDecorator クラスを拡張し、次のメソッドをオーバーライドします。
decorate- バックスタック内の各NavEntryに対して呼び出されるコンポーザブル ラムダ。NavEntryをパラメータとして受け取ります。これにより、エントリのcontentKeyにキー設定された状態オブジェクトを作成できます。CompositionLocalProviderを使用して、エントリのコンテンツに依存関係を指定できます。コンテンツをコンポーザブル関数で囲んだり、副作用をトリガーしたりすることもできます。このメソッド内では、必ずentry.Content()を呼び出す必要があります。onPop-NavEntryがバックスタックから削除され、コンポジションから離れたときに呼び出されるコールバック。削除されたエントリのcontentKeyを受け取ります。contentKeyを使用して、そのエントリに関連付けられた状態を特定してクリーンアップします。
次の例では、NavEntryDecorator クラスを拡張してカスタム デコレータを作成します。
// import androidx.navigation3.runtime.NavEntryDecorator class CustomNavEntryDecorator<T : Any> : NavEntryDecorator<T>( decorate = { entry -> Log.d("CustomNavEntryDecorator", "entry with ${entry.contentKey} entered composition and was decorated") entry.Content() }, onPop = { contentKey -> Log.d("CustomNavEntryDecorator", "entry with $contentKey was popped") } )
デコレータで状態にアクセスする必要がある場合は、その状態を作成するコンポーズ可能な関数を作成し、それを使用してデコレータを構築します。実装例については、rememberSaveableStateHolderNavEntryDecorator のソースコードをご覧ください。これにより、状態(SaveableStateHolder)が作成され、それを使用してデコレータが構築されます。
バックスタックを装飾する
NavEntryDecorator を作成したら、次のいずれかの方法でバックスタックのエントリを装飾します。
rememberDecoratedNavEntriesを使用します。この関数は、複数のバックスタックがあり、それぞれに独自のデコレータのセットがある場合に便利です(詳しくは、こちらのコードレシピをご覧ください)。この関数は、NavDisplayで使用できるNavEntryの装飾されたリストを返します。entryDecoratorsパラメータを使用して、デコレータをNavDisplayに直接指定します。NavDisplayは内部でrememberDecoratedNavEntriesを呼び出し、装飾されたエントリを表示します。
デフォルトのデコレータを含める
Navigation 3 には、NavEntry の状態を構成の変更やプロセスの終了後も保持できるようにする SaveableStateHolderNavEntryDecorator という名前のデフォルトのデコレータが含まれています。NavEntry コンテンツを SaveableStateProvider でラップし、NavEntry コンテンツ内の rememberSaveable 呼び出しが正しく機能するようにします。
デコレータが SaveableStateProvider を提供していない限り、提供されるデコレータのリストの最初のデコレータとして SaveableStateHolderNavEntryDecorator を含める必要があります。これは rememberSaveableStateHolderNavEntryDecorator を使用して作成されます。
次に例を示します。
// import androidx.navigation3.runtime.rememberSaveableStateHolderNavEntryDecorator NavDisplay( entryDecorators = listOf( rememberSaveableStateHolderNavEntryDecorator(), remember { CustomNavEntryDecorator() } ), // ... )
デコレータを使用するタイミング
デコレータを使用して、次のことができます。
- バックスタック内のすべての
NavEntryの依存関係を作成します。たとえば、ViewModelStoreNavEntryDecoratorはすべてのNavEntryに対してViewModelStoreを作成します。 - オブジェクトを複数の
NavEntryにスコープ設定します。たとえば、複数のエントリ間でViewModelを共有する場合などです。 - 複数の
NavEntryに対して同じアクションを実行します。たとえば、各エントリに対してロギング、デバッグ、トレース オペレーションを実行します。 - 同じコンポーズ可能な関数で
NavEntryをラップします。 NavEntryに関連付けられている状態をクリーンアップします。たとえば、バックスタックからエントリが削除されると、ViewModelStoreNavEntryDecoratorは関連付けられたViewModelStoreをクリアします。
デコレータを使用して次のことは行わないでください。
- 依存関係を 1 つの
NavEntryに渡します。 - バックスタックよりも広いスコープの依存関係を提供します。
どちらの場合も、代わりに NavEntry を作成するときに依存関係を直接渡します。
その他のコード例については、NavEntryDecorator をご覧ください。