「リストと詳細」レイアウトを作成する

リスト / 詳細は、1 つのペインを表示するデュアルペイン レイアウトで構成される UI パターンです。 アイテムのリストが表示され、別のペインには選択したアイテムの詳細が表示されます 選択します。

このパターンは、詳細な情報を提供するアプリケーションに特に有用です。 大規模なコレクションの要素に関する情報(メール クライアントなど) メールのリストと各メール メッセージの詳細な内容が含まれます。 リストと詳細は、アプリの分割など、重要度の低いパスにも使用できます。 設定をカテゴリのリストに変換し、各カテゴリの設定を 表示されます。

ListDetailPaneScaffold を使用して UI パターンを実装する

ListDetailPaneScaffold は、実装を簡素化するコンポーザブルです。 リスト / 詳細パターン。リストと詳細のスキャフォールドは、 リストペイン、詳細ペイン、オプションの追加ペインの 3 つのペインがあります。「 scaffold が画面スペースの計算を処理します。十分な画面サイズが リストペインの横に詳細ペインが表示されます。小画面の場合 すると、スキャフォールドは自動的にリストまたは 表示されます。

リストページの横に表示される詳細ペイン。
図 1. 十分な画面サイズがある場合は リストペインの横に表示されます。
アイテムが選択されると、詳細ペインが画面全体に表示されます。
図 2. 画面サイズが限られている場合は、詳細ペイン(アイテムが選択されているため) スペース全体を占有します。

依存関係の宣言

ListDetailPaneScaffoldマテリアル 3 アダプティブ レイアウトの一部です ライブラリをご覧ください。

アプリには、次の 3 つの関連するマテリアル 3 ライブラリの依存関係を含める必要があります。

  • adaptive - 下位レベルの構成要素(HingeInfo など) および Posture
  • adaptive-layout - 次のようなアダプティブ レイアウト ListDetailPaneScaffoldSupportingPaneScaffold
    • adaptive-navigation - 内部と外部を移動するためのコンポーザブル ペイン間

アプリまたはモジュールの build.gradle ファイルに依存関係を追加します。

Kotlin


implementation("androidx.compose.material3.adaptive:adaptive:1.0.0-alpha12")
implementation("androidx.compose.material3.adaptive:adaptive-layout:1.0.0-alpha12")
implementation("androidx.compose.material3.adaptive:adaptive-navigation:1.0.0-alpha12")

Groovy


implementation 'androidx.compose.material3.adaptive:adaptive:1.0.0-alpha12'
implementation 'androidx.compose.material3.adaptive:adaptive-layout:1.0.0-alpha12'
implementation 'androidx.compose.material3.adaptive:adaptive-navigation:1.0.0-alpha12'

基本的な使用方法

ListDetailPaneScaffold を次のように実装します。

  1. 選択されるコンテンツを表すクラスを使用します。このクラス 保存をサポートするには、Parcelable にする必要があります。 選択したリストアイテムを復元できますkotlin-parcelize を使用する プラグインを使用してコードを生成します。

    @Parcelize
    class MyItem(val id: Int) : Parcelable

  2. 次を使用して ThreePaneScaffoldNavigator を作成します: rememberListDetailPaneScaffoldNavigator を追加して BackHandler を追加します。この navigator は、リストペイン、詳細ペイン、追加ペインの間を移動するために使用します。方法 ジェネリック型を宣言すると、ナビゲータは scaffold(つまり、どの MyItem が表示されているか)を指定します。この型は Parcelable であれば、状態はナビゲータによって保存および復元され、 自動的に処理されます。「 BackHandler システムの「戻る」ジェスチャーまたは ] ボタンを離します。アプリの [戻る] ボタンの想定される動作は、 ListDetailPaneScaffold はウィンドウ サイズと現在のスキャフォールドに依存する あります。ListDetailPaneScaffold が以前の方法に戻ることをサポートできる場合 現在の状態では、canNavigateBack()true になり、 BackHandler

    val navigator = rememberListDetailPaneScaffoldNavigator<MyItem>()
    
    BackHandler(navigator.canNavigateBack()) {
        navigator.navigateBack()
    }

  3. scaffoldStatenavigator から ListDetailPaneScaffold コンポーザブル。

    ListDetailPaneScaffold(
        directive = navigator.scaffoldDirective,
        value = navigator.scaffoldValue,
        // ...
    )

  4. 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)
                    }
                )
            }
        },
        // ...
    )

  5. 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)
            }
        }
    },
)