Jetpack Compose Glimmer의 세로 스택

적용 가능한 XR 기기
이 안내는 이러한 유형의 XR 기기용 환경을 구축하는 데 도움이 됩니다.
디스플레이 글라스

Jetpack Compose Glimmer에서 VerticalStack은 시각적으로 겹치는 3차원 시퀀스로 항목을 정렬하는 지연 세로 스크롤 가능 레이아웃입니다. 기본 항목은 전경에 눈에 띄게 표시되고 후속 항목은 기본 항목 뒤에 배치됩니다.

그림 1. Jetpack Compose Glimmer의 다양한 스택 스타일의 예

스크롤 및 위치 지정 동작

스택은 항목을 겹치는 콤팩트한 레이아웃으로 정렬하므로 목록과 같은 다른 유형의 순차적 구성요소와는 다른 동작이 있습니다.

  • 사용자가 세로로 스크롤하면 활성 포그라운드 항목이 뷰에서 전환되어 바로 아래 항목이 눈에 띄는 포그라운드 위치로 슬라이드됩니다.
  • 항목은 항상 사용자의 동작이 끝난 후 특수 스프링 애니메이션을 사용하여 전경 위치로 스냅 애니메이션됩니다.
  • 항목은 z축을 따라 배치되며 목록에서 더 뒤에 있는 항목은 기본 항목 뒤에 배치됩니다.

포커스 관리

VerticalStack는 전문화된 포커스 시스템을 사용하여 현재 포그라운드 항목이 항상 사용자 상호작용의 기본 타겟이 되도록 합니다.

  • 초기 포커스 및 재진입: 초기 포커스 및 포커스 재진입은 스택의 현재 상단 항목으로 이동합니다.
  • 자동 초점 알림: 항목이 전환되면 스택에서 상단 항목의 포커스를 요청합니다.
  • 포커스 추적: 각 항목은 onFocusChanged를 사용하여 StackState에 개별 포커스 상태를 알립니다.

예: 세로 스택 만들기

다음 코드는 여러 항목이 있는 세로 스택을 만듭니다.

@Composable
fun VerticalStackSample() {
    VerticalStack(modifier = Modifier.fillMaxWidth().height(364.dp)) {
        item(key = 0) {
            Card(modifier = Modifier.fillMaxSize().itemDecoration(CardDefaults.shape)) {
                Text(
                    "Item-0",
                    style = LocalTextStyle.current.copy(textMotion = TextMotion.Animated),
                )
            }
        }
        items(count = 10, key = { it + 1 }) { index ->
            Card(modifier = Modifier.fillMaxSize().itemDecoration(CardDefaults.shape)) {
                Text(
                    "Item-${index + 1}",
                    style = LocalTextStyle.current.copy(textMotion = TextMotion.Animated),
                )
            }
        }
    }
}

코드에 관한 핵심 사항

  • 텍스트의 LocalTextStyle에 대한 textMotionAnimated로 설정합니다. 이렇게 하면 레이아웃 애니메이션이나 크기 조절 전환 중에 텍스트가 부드럽게 렌더링되어 픽셀 스냅 아티팩트가 방지됩니다.
  • 세로 스택의 높이에 대해 특정 크기의 364.dp를 제공합니다. 항상 특정 높이를 제공하거나, 높이 수정자를 사용하거나, fillMaxSize 수정자를 적용하여 카드 전환의 시각적 영역을 정의하세요.
  • 모양 매개변수를 직접 사용하는 다른 구성요소와 달리 VerticalStackitemDecoration 수정자를 사용하여 항목의 시각적 경계를 관리합니다. 이 예에서는 일관된 클리핑과 시각적 효과를 유지하기 위해 초기 항목의 itemDecoration를 모든 하위 항목과 동일한 모양으로 전달합니다. 이 예시에서는 기본 CardDefaults.shape을 사용합니다.