목록 세부정보는 하나의 창은 항목 목록을 표시하고 다른 창에는 목록에서 선택한 항목의 세부정보를 표시하는 이중 창 레이아웃으로 구성된 UI 패턴입니다.
이 패턴은 이메일 목록과 각 이메일 메시지의 세부 콘텐츠가 있는 이메일 클라이언트와 같이 대규모 컬렉션 요소에 대한 심층 정보를 제공하는 애플리케이션에 특히 유용합니다. 목록-세부정보는 앱 환경설정을 세부정보 창에 각 카테고리의 환경설정이 있는 카테고리 목록으로 분할하는 등 중요도가 낮은 경로에도 사용할 수 있습니다.
ListDetailPaneScaffold
로 UI 패턴 구현
ListDetailPaneScaffold
는 앱에서 목록-세부정보 패턴의 구현을 간소화하는 컴포저블입니다. 목록 세부정보 스캐폴드는 목록 창, 세부정보 창, 선택적 추가 창 등 최대 세 개의 창으로 구성될 수 있습니다. Scaffold는 화면 공간 계산을 처리합니다. 충분한 화면 크기가 있으면 목록 창과 함께 세부정보 창이 표시됩니다. 작은 화면 크기에서는 Scaffold가 자동으로 목록 창 또는 세부정보 창 전체 화면을 표시하도록 전환됩니다.
종속 항목 선언
ListDetailPaneScaffold
는 Material 3 적응형 레이아웃 라이브러리의 일부입니다.
앱에는 다음과 같은 세 가지 관련 Material 3 라이브러리의 종속 항목이 포함되어야 합니다.
- 적응형 —
HingeInfo
,Posture
와 같은 하위 수준 빌딩 블록 - adaptive-layout - 적응형 레이아웃(예:
ListDetailPaneScaffold
,SupportingPaneScaffold
) - 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
를 구현합니다.
선택할 콘텐츠를 나타내는 클래스를 사용합니다. 선택한 목록 항목의 저장 및 복원을 지원하려면 이 클래스가
Parcelable
이어야 합니다. kotlin-parcelize 플러그인을 사용하여 코드를 생성합니다.@Parcelize class MyItem(val id: Int) : Parcelable
rememberListDetailPaneScaffoldNavigator
로ThreePaneScaffoldNavigator
를 만들고BackHandler
를 추가합니다. 이 탐색기는 목록, 세부정보, 추가 창 간에 이동하는 데 사용됩니다. 일반 유형을 선언하면 탐색기는 Scaffold의 상태 (즉,MyItem
가 표시되고 있음)도 추적합니다. 이 유형은 parcelable이므로 상태를 저장하고 탐색기에서 복원하여 구성 변경을 자동으로 처리할 수 있습니다.BackHandler
는 시스템 뒤로 동작 또는 버튼을 사용하여 뒤로 이동하는 기능을 지원합니다.ListDetailPaneScaffold
의 뒤로 버튼에 예상되는 동작은 창 크기와 현재 Scaffold 값에 따라 다릅니다.ListDetailPaneScaffold
가 현재 상태로 되돌리는 것을 지원할 수 있는 경우canNavigateBack()
는true
가 되어BackHandler
를 사용 설정합니다.val navigator = rememberListDetailPaneScaffoldNavigator<MyItem>() BackHandler(navigator.canNavigateBack()) { navigator.navigateBack() }
scaffoldState
를navigator
에서ListDetailPaneScaffold
컴포저블로 전달합니다.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) } } }, )