펼친 상태의 대형 디스플레이와 고유한 접힌 상태는 폴더블 기기에서 새로운 사용자 환경을 제공합니다. Jetpack Compose에서 앱이 접힌 상태를 인식하도록 하려면 접힘, 힌지, 기기 상태와 같은 폴더블 기기 창 기능에 API를 제공하는 Compose Material 3 Adaptive 라이브러리를 사용합니다. 앱이 접힌 상태를 인식하는 경우 접힘 또는 힌지 영역에 중요한 콘텐츠를 배치하지 않고 접힘과 힌지를 자연스러운 구분선으로 사용하도록 레이아웃을 조정할 수 있습니다.
기기가 탁자 모드 또는 책 모드와 같은 구성을 지원하는지 이해하면 다양한 레이아웃을 지원하거나 특정 기능을 제공하는 것에 관한 결정을 내리는 데 도움이 될 수 있습니다.
창 정보
Jetpack Compose에서 collectFoldingFeaturesAsState() 구성 가능한
함수를 사용하여 창 접기 정보를 관찰합니다.
collectFoldingFeaturesAsState()는 현재 창 접기 기능
WindowInfoTracker에서 FoldingFeature`FoldingFeature` 객체 목록이 포함된 Compose State로 수집합니다.
collectFoldingFeaturesAsState()는 Compose State를 반환하므로
구성 가능한 항목이 수동 수명 주기 관리 또는 흐름 수집 없이 기기 접기 상태 또는 상태가
변경될 때마다 자동으로 재구성됩니다.
@Composable
fun FoldAwareScreen() {
val foldingFeatures by collectFoldingFeaturesAsState()
// Access folding features for the current window.
val foldFeature = foldingFeatures.firstOrNull()
if (foldFeature != null) {
// Adapt layout based on the fold feature.
}
}
폴더블 디스플레이 기능
FoldingFeature 요소 목록 (DisplayFeature의 하위 유형)
은 다음과 같은
속성을 비롯하여 폴더블 디스플레이에 관한 정보를 제공합니다.collectFoldingFeaturesAsState()
state: 기기의 접힌 상태(FLAT또는HALF_OPENED)orientation: 접힘 또는 힌지의 방향,HORIZONTAL또는VERTICALisSeparating: 접힘 또는 힌지가 두 개의 논리 디스플레이 영역을 생성하는지 여부(true 또는 false)
HALF_OPENED인 폴더블 기기는 화면이 두 개의 디스플레이 영역으로 분리되므로 항상 isSeparating을 true로 보고합니다. 듀얼 화면 기기에서 애플리케이션이 두 화면에 걸쳐 있는 경우 isSeparating은 항상 true입니다.
FoldingFeature bounds 속성 (DisplayFeature에서 상속됨)
은 접힘 또는 힌지와 같은 접기 기능의 경계 직사각형을 나타냅니다.
경계는 접기 기능을 기준으로 화면에 요소를 배치하는 데 사용할 수 있습니다.
@Composable
fun FoldFeatureDemo() {
val foldingFeatures by collectFoldingFeaturesAsState()
val foldFeature = foldingFeatures.firstOrNull()
if (foldFeature != null) {
val isSeparating = foldFeature.isSeparating
val occlusionType = foldFeature.occlusionType
val bounds = foldFeature.bounds
// Use bounds and properties to position content.
}
}
탁자 모드
FoldingFeature 객체에 포함된 정보를 사용하여 앱에서 휴대전화가 표면에 있고, 힌지가 수평 위치에 있으며, 폴더블 화면이 절반 정도 열려 있는 탁자 모드와 같은 상태를 지원할 수 있습니다.
탁자 모드는 사용자가 휴대전화를 손에 쥐고 있지 않은 상태에서 휴대전화를 조작할 수 있는 편리함을 제공합니다. 탁자 모드는 미디어를 보고, 사진을 찍고, 영상 통화를 할 때 적합합니다.
collectFoldingFeaturesAsState()의 FoldingFeature.State 및 FoldingFeature.Orientation을 사용하여 기기가 탁자
모드인지 확인할 수 있습니다.
@Composable
fun TabletopContent() {
val foldingFeatures by collectFoldingFeaturesAsState()
val foldFeature = foldingFeatures.firstOrNull()
val isTableTopPosture = foldFeature != null &&
foldFeature.state == FoldingFeature.State.HALF_OPENED &&
foldFeature.orientation == FoldingFeature.Orientation.HORIZONTAL
if (isTableTopPosture) {
// Tabletop layout: separate content and controls across the fold.
} else {
// Standard layout.
}
}
또는 창이 탁자 모드인지 확인하려면
Posture 속성을 확인하여
currentWindowAdaptiveInfoV2() 확인할 수 있습니다.
val adaptiveInfo = currentWindowAdaptiveInfoV2()
val isTabletop = adaptiveInfo.windowPosture.isTabletop
기기가 탁자 모드임을 알면 그에 따라 앱 레이아웃을 업데이트합니다. 미디어 앱의 경우 일반적으로 스크롤 없이 볼 수 있는 부분에 재생을 배치하고, 핸즈프리 보기 또는 청취 환경을 위해 위치 지정 컨트롤과 보조 콘텐츠를 바로 아래에 배치하는 것을 의미합니다.
예
MediaPlayerActivity앱: Media3 Exoplayer 및 WindowManager를 사용하여 접기 인식 동영상 플레이어를 만드는 방법을 참고하세요.Jetpack WindowManager로 폴더블 기기에서 카메라 앱 최적화하기 Codelab: 사진 앱에 탁자 모드를 구현하는 방법을 알아봅니다. 뷰파인더는 화면의 상단 (스크롤 없이 볼 수 있는 부분)에 표시하고 컨트롤은 화면의 하단에 표시합니다.
책 모드
또 다른 고유한 폴더블 기능은 기기가 반쯤 열려 있고 힌지가 수직인 책 모드입니다. 책 모드는 eBook을 읽을 때 유용합니다. 책 모드는 대형 폴더블 화면에 열린 2페이지 레이아웃을 제본된 책처럼 사용하여 실제 책을 읽는 듯한 경험을 제공합니다.
핸즈프리로 사진을 찍을 때 다른 가로세로 비율을 캡처하려는 경우 사진에도 사용할 수 있습니다.
탁자 모드에 사용된 것과 동일한 기법으로 책 모드를 구현합니다. 접기 기능 방향이 가로가 아닌 세로인지 확인합니다.
@Composable
fun BookContent() {
val foldingFeatures by collectFoldingFeaturesAsState()
val foldFeature = foldingFeatures.firstOrNull()
val isBookPosture = foldFeature != null &&
foldFeature.state == FoldingFeature.State.HALF_OPENED &&
foldFeature.orientation == FoldingFeature.Orientation.VERTICAL
if (isBookPosture) {
// Book posture layout: two-page layout across the vertical fold.
} else {
// Standard single-page layout.
}
}
창 크기 변경
기기 구성이 변경되면(예: 기기가 접히거나 펼쳐지는 경우, 회전되는 경우, 멀티 윈도우 모드에서 크기가 조절되는 경우) 앱의 디스플레이 영역이 변경될 수 있습니다.
Jetpack
Compose에서 현재 창 크기 클래스를 가져오고 크기 변경에 맞게 조정하려면 currentWindowAdaptiveInfoV2() 구성 가능한 함수를 사용합니다.
Compose Material 3 Adaptive 라이브러리 currentWindowAdaptiveInfoV2()
는 기본적으로 대형 및 초대형 중단점을 지원하는 현재 창의
WindowSizeClass와 기기의
windowPosture를 제공하는 WindowAdaptiveInfo 인스턴스를 반환합니다.
@Composable
fun AdaptiveApp() {
val adaptiveInfo = currentWindowAdaptiveInfoV2()
val windowSizeClass = adaptiveInfo.windowSizeClass
when {
windowSizeClass.isWidthAtLeastBreakpoint(
WIDTH_DP_EXPANDED_LOWER_BOUND
) -> {
// Expanded layout
}
windowSizeClass.isWidthAtLeastBreakpoint(
WIDTH_DP_MEDIUM_LOWER_BOUND
) -> {
// Medium layout
}
else -> {
// Compact layout
}
}
}
창 크기 클래스 사용을 참고하세요.
추가 리소스
접힌 상태를 인식하는 레이아웃 및 폴더블 기기에 관해 자세히 알아보려면 다음 리소스를 참고하세요.
샘플
- Jetpack WindowManager 샘플: Jetpack WindowManager 라이브러리 사용 방법의 예
- Jetcaster : Compose를 사용한 탁자 모드 구현