リストと詳細は、1 つのペインにアイテムのリストが表示され、別のペインにリストから選択したアイテムの詳細が表示される、デュアルペイン レイアウトで構成される UI パターンです。
このパターンは、メールのリストと各メール メッセージの詳細なコンテンツを含むメール クライアントなど、大規模なコレクションの要素に関する詳細情報を提供するアプリケーションに特に便利です。リスト詳細は、アプリの設定をカテゴリのリストに分割し、詳細ペインに各カテゴリの設定を表示するなど、重要性の低いパスにも使用できます。
ListDetailPaneScaffold
を使用して UI パターンを実装する
ListDetailPaneScaffold
は、アプリでリストと詳細のパターンの実装を簡素化するコンポーザブルです。リストと詳細のスクロールフローは、リストペイン、詳細ペイン、オプションの追加ペインの最大 3 つのペインで構成できます。スキャフォールドは、画面領域の計算を処理します。十分な画面サイズが使用可能な場合は、詳細ペインがリストペインと一緒に表示されます。小さい画面サイズでは、スキャフォールドはリストペインまたは詳細ペインを全画面表示に自動的に切り替えます。
依存関係の宣言
ListDetailPaneScaffold
は マテリアル 3 アダプティブ レイアウト ライブラリの一部です。
アプリまたはモジュールの build.gradle
ファイルに、次の 3 つの関連する依存関係を追加します。
Kotlin
implementation("androidx.compose.material3.adaptive:adaptive") implementation("androidx.compose.material3.adaptive:adaptive-layout") implementation("androidx.compose.material3.adaptive:adaptive-navigation")
Groovy
implementation 'androidx.compose.material3.adaptive:adaptive' implementation 'androidx.compose.material3.adaptive:adaptive-layout' implementation 'androidx.compose.material3.adaptive:adaptive-navigation'
- 適応型 -
HingeInfo
やPosture
などの低レベルのビルディング ブロック - adaptive-layout -
ListDetailPaneScaffold
やSupportingPaneScaffold
などのアダプティブ レイアウト - adaptive-navigation - ペイン内とペイン間の移動用のコンポーザブル
基本的な使用方法
ListDetailPaneScaffold
を次のように実装します。
選択するコンテンツを表すクラスを使用します。選択したリストアイテムの保存と復元をサポートするには、このクラスを
Parcelable
にする必要があります。kotlin-parcelize プラグインを使用してコードを生成します。@Parcelize class MyItem(val id: Int) : Parcelable
rememberListDetailPaneScaffoldNavigator
でThreePaneScaffoldNavigator
を作成し、BackHandler
を追加します。このナビゲータは、リストペイン、詳細ペイン、追加ペイン間を移動するために使用します。汎用型を宣言することで、ナビゲータはスキャフォールドの状態(表示されているMyItem
)も追跡します。この型はパーセル可能であるため、ナビゲータによって状態を保存して復元し、構成変更を自動的に処理できます。BackHandler
は、システムの戻るジェスチャーまたはボタンを使用して戻るナビゲーションをサポートします。ListDetailPaneScaffold
の [戻る] ボタンの想定される動作は、ウィンドウのサイズと現在のスキャフォールド値によって異なります。ListDetailPaneScaffold
が現在の状態での戻りをサポートできる場合、canNavigateBack()
はtrue
になり、BackHandler
が有効になります。val navigator = rememberListDetailPaneScaffoldNavigator<MyItem>() BackHandler(navigator.canNavigateBack()) { navigator.navigateBack() }
navigator
からListDetailPaneScaffold
コンポーザブルにscaffoldState
を渡します。ListDetailPaneScaffold( directive = navigator.scaffoldDirective, value = navigator.scaffoldValue, // ... )
リストペインの実装を
ListDetailPaneScaffold
に指定します。AnimatedPane
を使用して、ナビゲーション中にデフォルトのペイン アニメーションを適用します。次に、ThreePaneScaffoldNavigator
を使用して詳細ペインListDetailPaneScaffoldRole.Detail
に移動し、渡されたアイテムを表示します。ListDetailPaneScaffold( directive = navigator.scaffoldDirective, value = navigator.scaffoldValue, listPane = { AnimatedPane { MyList( onItemClick = { item -> // Navigate to the detail pane with the passed item navigator.navigateTo(ListDetailPaneScaffoldRole.Detail, item) } ) } }, // ... )
詳細ペインの実装を
ListDetailPaneScaffold
に含めます。ナビゲーションが完了すると、currentDestination
には、アプリが移動したペイン(ペインに表示されるコンテンツを含む)が含まれます。content
プロパティは、元の remember 呼び出しで指定されたタイプ(この例ではMyItem
)と同じであるため、表示する必要があるデータのプロパティにもアクセスできます。ListDetailPaneScaffold( directive = navigator.scaffoldDirective, value = navigator.scaffoldValue, listPane = // ... detailPane = { AnimatedPane { navigator.currentDestination?.content?.let { MyDetails(it) } } }, )
上記の手順を実装すると、コードは次のようになります。
val navigator = rememberListDetailPaneScaffoldNavigator<MyItem>() BackHandler(navigator.canNavigateBack()) { navigator.navigateBack() } ListDetailPaneScaffold( directive = navigator.scaffoldDirective, value = navigator.scaffoldValue, listPane = { AnimatedPane { MyList( onItemClick = { item -> // Navigate to the detail pane with the passed item navigator.navigateTo(ListDetailPaneScaffoldRole.Detail, item) }, ) } }, detailPane = { AnimatedPane { // Show the detail pane content if selected item is available navigator.currentDestination?.content?.let { MyDetails(it) } } }, )