リスト詳細は、デュアルペイン レイアウトで構成される UI パターンです。1 つのペインにはアイテムのリストが表示され、別のペインにはリストから選択されたアイテムの詳細が表示されます。
このパターンは、大規模なコレクションの要素に関する詳細情報を提供するアプリケーションに特に便利です。たとえば、メールのリストと各メール メッセージの詳細なコンテンツがあるメール クライアントなどです。リスト / 詳細は、重要度の低いパスにも使用できます。たとえば、アプリの設定をカテゴリのリストに分割し、詳細ペインに各カテゴリの設定を表示する場合などです。
ListDetailPaneScaffold
で UI パターンを実装する
ListDetailPaneScaffold
は、アプリでのリスト詳細パターンの実装を簡素化するコンポーザブルです。リストと詳細のスキャフォールドは最大 3 つのペイン(リストペイン、詳細ペイン、オプションの追加ペイン)で構成できます。スキャフォールドは画面スペースの計算を処理します。十分な画面サイズを使用できる場合、詳細ペインがリストペインと並んで表示されます。小さい画面サイズでは、スキャフォールドが自動的に切り替わり、リストペインまたは詳細ペインが全画面表示されます。
依存関係の宣言
ListDetailPaneScaffold
は、マテリアル 3 アダプティブ ライブラリの一部です。アプリまたはモジュールの build.gradle
ファイルにライブラリの依存関係を追加します。
implementation("androidx.compose.material3.adaptive:adaptive:1.0.0-alpha07")
implementation("androidx.compose.material3.adaptive:adaptive-layout:1.0.0-alpha07")
implementation("androidx.compose.material3.adaptive:adaptive-navigation:1.0.0-alpha07")
基本的な使用方法
ListDetailPaneScaffold
の基本的な使用方法は次のとおりです。
リストから現在選択されているアイテムを変更可能な状態変数に格納します。この変数は、詳細ペインに表示される項目を保持します。通常は、現在選択されているアイテムを
null
で初期化し、まだ選択されていないことを示します。class MyItem(val id: Int) { companion object { val Saver: Saver<MyItem?, Int> = Saver( { it?.id }, ::MyItem, ) } }
var selectedItem: MyItem? by rememberSaveable(stateSaver = MyItem.Saver) { mutableStateOf(null) }
rememberListDetailPaneScaffoldNavigator
を使用してThreePaneScaffoldNavigator
を作成し、BackHandler
を追加します。このナビゲータは、リスト、詳細、追加ペイン間を移動し、スキャフォールドに状態を提供するために使用されます。追加されたBackHandler
は、システムの「戻る」ジェスチャーまたはボタンを使用して戻る操作をサポートしています。ListDetailPaneScaffold
の [戻る] ボタンの想定される動作は、ウィンドウ サイズと現在のスキャフォールド値によって異なります。ListDetailPaneScaffold
が現在の状態への戻ることをサポートできる場合、canNavigateBack()
はtrue
になり、BackHandler
が有効になります。val navigator = rememberListDetailPaneScaffoldNavigator<Nothing>() BackHandler(navigator.canNavigateBack()) { navigator.navigateBack() }
作成した
navigator
からscaffoldState
をListDetailPaneScaffold
コンポーザブルに渡します。ListDetailPaneScaffold( directive = navigator.scaffoldDirective, value = navigator.scaffoldValue, // ... )
リストペインの実装を
ListDetailPaneScaffold
に指定します。実装に、新しく選択されたアイテムをキャプチャするためのコールバック引数が含まれていることを確認します。このコールバックがトリガーされたら、selectedItem
状態変数を更新し、ThreePaneScaffoldNavigator
を使用して詳細ペイン(ListDetailPaneScaffoldRole.Detail
)を表示します。ListDetailPaneScaffold( directive = navigator.scaffoldDirective, value = navigator.scaffoldValue, listPane = { AnimatedPane(Modifier) { MyList( onItemClick = { id -> // Set current item selectedItem = id // Switch focus to detail pane navigator.navigateTo(ListDetailPaneScaffoldRole.Detail) } ) } }, // ... )
ListDetailPaneScaffold
に詳細ペインの実装を含めます。selectedItem
が null でない場合にのみ、詳細コンテンツを表示します。ListDetailPaneScaffold( directive = navigator.scaffoldDirective, value = navigator.scaffoldValue, listPane = // ... detailPane = { AnimatedPane(Modifier) { selectedItem?.let { item -> MyDetails(item) } } }, )
上記の手順を実装すると、コードは次のようになります。
// Currently selected item var selectedItem: MyItem? by rememberSaveable(stateSaver = MyItem.Saver) { mutableStateOf(null) } // Create the ListDetailPaneScaffoldState val navigator = rememberListDetailPaneScaffoldNavigator<Nothing>() BackHandler(navigator.canNavigateBack()) { navigator.navigateBack() } ListDetailPaneScaffold( directive = navigator.scaffoldDirective, value = navigator.scaffoldValue, listPane = { AnimatedPane(Modifier) { MyList( onItemClick = { id -> // Set current item selectedItem = id // Display the detail pane navigator.navigateTo(ListDetailPaneScaffoldRole.Detail) }, ) } }, detailPane = { AnimatedPane(Modifier) { // Show the detail pane content if selected item is available selectedItem?.let { item -> MyDetails(item) } } }, )