지원 창 레이아웃은 관련 지원 정보를 표시하면서 사용자의 관심을 앱의 기본 콘텐츠에 유지합니다. 예를 들어 기본 창에는 영화에 관한 세부정보가 표시되고 보조 창에는 유사한 영화, 동일한 감독의 영화 또는 동일한 배우가 출연한 작품이 표시될 수 있습니다.
자세한 내용은 Material 3 지원 창 가이드라인을 참고하세요.
NavigableSupportingPaneScaffold를 사용하여 지원 창 구현
NavigableSupportingPaneScaffold
는 Jetpack Compose에서 지원 창 레이아웃을 간소화하는 컴포저블입니다. SupportingPaneScaffold
를 래핑하고 내장 탐색 및 뒤로 탐색 예측 처리를 추가합니다.
지원 창 스케폴드는 최대 3개의 창을 지원합니다.
- 기본 창: 기본 콘텐츠를 표시합니다.
- 지원 창: 기본 창과 관련된 추가 컨텍스트 또는 도구를 제공합니다.
- 추가 창 (선택사항): 필요한 경우 보충 콘텐츠에 사용됩니다.
스켈레톤은 창 크기에 따라 조정됩니다.
- 대형 창에서는 기본 창과 지원 창이 나란히 표시됩니다.
작은 창에서는 한 번에 하나의 창만 표시되며 사용자가 탐색할 때 전환됩니다.
그림 1. 지원 창 레이아웃
종속 항목 추가
NavigableSupportingPaneScaffold
는 Material 3 적응형 레이아웃 라이브러리의 일부입니다.
앱 또는 모듈의 build.gradle
파일에 다음과 같은 관련 종속 항목 세 개를 추가합니다.
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: 창 내부 및 간에 탐색하기 위한 컴포저블과 기본적으로 탐색을 지원하는 적응형 레이아웃(예:
NavigableListDetailPaneScaffold
및NavigableSupportingPaneScaffold
)
프로젝트에 compose-material3-adaptive 버전 1.1.0-beta1 이상이 포함되어 있는지 확인합니다.
뒤로 탐색 예측 동작 선택
Android 15 이하에서 뒤로 탐색 예측 애니메이션을 사용 설정하려면 뒤로 탐색 예측 동작을 지원하도록 선택해야 합니다. 선택하려면 AndroidManifest.xml
파일의 <application>
태그에 android:enableOnBackInvokedCallback="true"
를 추가하거나 <application>
태그 또는 개별 <activity>
태그에 android:enableOnBackInvokedCallback="true"
를 추가합니다.
앱이 Android 16 (API 수준 36) 이상을 타겟팅하면 뒤로 탐색 예측이 기본적으로 사용 설정됩니다.
탐색기 만들기
작은 창에서는 한 번에 하나의 창만 표시되므로 ThreePaneScaffoldNavigator
를 사용하여 창 간에 이동합니다. rememberSupportingPaneScaffoldNavigator
를 사용하여 탐색기 인스턴스를 만듭니다.
val scaffoldNavigator = rememberSupportingPaneScaffoldNavigator() val scope = rememberCoroutineScope()
탐색기를 스캐폴드에 전달
스캐폴드에는 스캐폴드의 상태를 나타내는 인터페이스인 ThreePaneScaffoldNavigator
, ThreePaneScaffoldValue
, PaneScaffoldDirective
가 필요합니다.
NavigableSupportingPaneScaffold( navigator = scaffoldNavigator, mainPane = { /*...*/ }, supportingPane = { /*...*/ }, )
기본 창과 지원 창은 콘텐츠가 포함된 컴포저블입니다. AnimatedPane
를 사용하여 탐색 중에 기본 창 애니메이션을 적용합니다. 스캐폴드 값을 사용하여 지원 창이 숨겨져 있는지 확인합니다. 숨겨져 있으면 navigateTo(SupportingPaneScaffoldRole.Supporting)
를 호출하여 지원 창을 표시하는 버튼을 표시합니다.
다음은 스캐폴드의 전체 구현입니다.
val scaffoldNavigator = rememberSupportingPaneScaffoldNavigator() val scope = rememberCoroutineScope() NavigableSupportingPaneScaffold( navigator = scaffoldNavigator, mainPane = { AnimatedPane( modifier = Modifier .safeContentPadding() .background(Color.Red) ) { if (scaffoldNavigator.scaffoldValue[SupportingPaneScaffoldRole.Supporting] == PaneAdaptedValue.Hidden) { Button( modifier = Modifier .wrapContentSize(), onClick = { scope.launch { scaffoldNavigator.navigateTo(SupportingPaneScaffoldRole.Supporting) } } ) { Text("Show supporting pane") } } else { Text("Supporting pane is shown") } } }, supportingPane = { AnimatedPane(modifier = Modifier.safeContentPadding()) { Text("Supporting pane") } } )
창 컴포저블 추출
SupportingPaneScaffold
의 개별 창을 자체 컴포저블로 추출하여 재사용 가능하고 테스트 가능하도록 합니다. 기본 애니메이션을 사용하려면 ThreePaneScaffoldScope
를 사용하여 AnimatedPane
에 액세스합니다.
@OptIn(ExperimentalMaterial3AdaptiveApi::class) @Composable fun ThreePaneScaffoldPaneScope.MainPane( shouldShowSupportingPaneButton: Boolean, onNavigateToSupportingPane: () -> Unit, modifier: Modifier = Modifier, ) { AnimatedPane( modifier = modifier.safeContentPadding() ) { // Main pane content if (shouldShowSupportingPaneButton) { Button(onClick = onNavigateToSupportingPane) { Text("Show supporting pane") } } else { Text("Supporting pane is shown") } } } @OptIn(ExperimentalMaterial3AdaptiveApi::class) @Composable fun ThreePaneScaffoldPaneScope.SupportingPane( modifier: Modifier = Modifier, ) { AnimatedPane(modifier = modifier.safeContentPadding()) { // Supporting pane content Text("This is the supporting pane") } }
창을 컴포저블로 추출하면 SupportingPaneScaffold
사용이 간소화됩니다 (다음을 이전 섹션의 스캐폴드 전체 구현과 비교하세요).
val scaffoldNavigator = rememberSupportingPaneScaffoldNavigator() val scope = rememberCoroutineScope() NavigableSupportingPaneScaffold( navigator = scaffoldNavigator, mainPane = { MainPane( shouldShowSupportingPaneButton = scaffoldNavigator.scaffoldValue.secondary == PaneAdaptedValue.Hidden, onNavigateToSupportingPane = { scope.launch { scaffoldNavigator.navigateTo(ThreePaneScaffoldRole.Secondary) } } ) }, supportingPane = { SupportingPane() }, )
스캐폴드의 특정 측면을 더 세부적으로 제어해야 하는 경우 NavigableSupportingPaneScaffold
대신 SupportingPaneScaffold
를 사용하는 것이 좋습니다. PaneScaffoldDirective
및 ThreePaneScaffoldValue
또는 ThreePaneScaffoldState
를 별도로 허용합니다. 이러한 유연성을 통해 창 간격에 관한 맞춤 로직을 구현하고 동시에 표시해야 하는 창 수를 결정할 수 있습니다. ThreePaneScaffoldPredictiveBackHandler
를 추가하여 뒤로 탐색 예측 지원을 사용 설정할 수도 있습니다.
ThreePaneScaffoldPredictiveBackHandler
추가
스캐폴드 탐색기 인스턴스를 사용하는 뒤로 탐색 예측 핸들러를 연결하고 backBehavior
를 지정합니다. 이를 통해 뒤로 탐색 중에 백 스택에서 대상이 팝되는 방식을 결정합니다. 그런 다음 scaffoldDirective
및 scaffoldState
를 SupportingPaneScaffold
에 전달합니다. ThreePaneScaffoldState
를 허용하는 오버로드를 사용하여 scaffoldNavigator.scaffoldState
를 전달합니다.
SupportingPaneScaffold
내에서 기본 창과 지원 창을 정의합니다. 기본 창 애니메이션에는 AnimatedPane
를 사용합니다.
이 단계를 구현하면 코드가 다음과 같이 표시됩니다.
val scaffoldNavigator = rememberSupportingPaneScaffoldNavigator() val scope = rememberCoroutineScope() ThreePaneScaffoldPredictiveBackHandler( navigator = scaffoldNavigator, backBehavior = BackNavigationBehavior.PopUntilScaffoldValueChange ) SupportingPaneScaffold( directive = scaffoldNavigator.scaffoldDirective, scaffoldState = scaffoldNavigator.scaffoldState, mainPane = { MainPane( shouldShowSupportingPaneButton = scaffoldNavigator.scaffoldValue.secondary == PaneAdaptedValue.Hidden, onNavigateToSupportingPane = { scope.launch { scaffoldNavigator.navigateTo(ThreePaneScaffoldRole.Secondary) } } ) }, supportingPane = { SupportingPane() }, )