목록-세부정보 레이아웃 빌드

목록-세부정보는 하나의 창이 있는 이중 창 레이아웃으로 구성된 UI 패턴입니다. 는 항목 목록을 표시하고 다른 창에는 선택한 항목의 세부정보를 표시합니다. 목록에서 삭제됩니다.

이 패턴은 특히 심층적인 분석을 제공하는 애플리케이션에 이메일 클라이언트 등 대규모 컬렉션의 요소에 대한 정보 이메일 목록 및 각 이메일 메시지의 세부 내용이 포함되어 있습니다. 목록-세부정보는 앱 분할과 같이 덜 중요한 경로에도 사용할 수 있습니다. 환경설정에서 각 카테고리에 대한 환경설정과 함께 카테고리 목록으로 확인할 수 있습니다

ListDetailPaneScaffold로 UI 패턴 구현

ListDetailPaneScaffold는 앱의 목록-세부정보 패턴을 지원합니다. 목록-세부정보 Scaffold는 최대 세 개의 창: 목록 창, 세부정보 창, 선택적인 추가 창입니다. 이 Scaffold는 화면 공간 계산을 처리합니다. 충분한 화면 크기가 세부정보 창이 목록 창 옆에 표시됩니다. 작은 화면에서 Scaffold가 자동으로 전환되어 목록 또는 세부정보 창 전체 화면

목록 페이지와 함께 표시되는 세부정보 창
그림 1. 충분한 화면 크기를 사용할 수 있는 경우 세부정보 이 창이 목록 창 옆에 표시됩니다.
항목을 선택하면 세부정보 창에 전체 화면이 표시됩니다.
그림 2. 화면 크기가 제한되면 항목이 선택되었으므로 세부정보 창 전체 공간을 차지합니다.

종속 항목 선언

ListDetailPaneScaffoldMaterial 3 적응형 레이아웃의 일부입니다. 라이브러리로 이동합니다.

앱에는 다음과 같은 세 가지 관련 Material 3 라이브러리의 종속 항목이 포함되어야 합니다.

  • 적응형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를 추가합니다. 이 탐색기를 사용하여 목록 창, 세부정보 창, 추가 창 간에 이동합니다. 기준 일반 유형을 선언하면 탐색기는 Scaffold (즉, MyItem가 표시됨) 이 유형은 parcelable을 추가하면 탐색기에서 상태를 저장하고 복원하여 구성 변경을 자동으로 처리합니다 이 BackHandler 드림 시스템 뒤로 동작을 사용하여 뒤로 탐색을 지원하거나 버튼을 클릭합니다. 다음에 대한 뒤로 버튼의 예상 동작은 ListDetailPaneScaffold는 창 크기와 현재 Scaffold에 따라 다릅니다. 값에 사용합니다. 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)
            }
        }
    },
)