목록을 사용하면 사용자는 Wear OS 기기에서 여러 선택 항목 중 하나를 고를 수 있습니다.
많은 Wear OS 기기가 원형 화면을 사용하므로 화면의 상단과 하단 근처에 표시되는 목록 항목을 보기가 어렵습니다. 이러한 이유로
Wear OS용 Compose에는 크기 조정 및 모핑 애니메이션을 지원하는
TransformingLazyColumn이라는 LazyColumn 클래스의 한 가지 버전이 포함되어 있습니다.
항목이 가장자리로 이동하면 항목이 더 작아지고 페이드아웃됩니다.
권장되는 크기 조정 및 스크롤 효과를 적용하려면 다음 단계를 따르세요.
Modifier.transformedHeight를 사용하여 항목이 화면을 스크롤할 때 Compose에서 높이 변경사항을 계산하도록 허용합니다.transformation = SurfaceTransformation(transformationSpec)을 사용하여 항목 콘텐츠 축소 등 시각적 효과를 적용합니다.- `
transformation`을 매개변수로 사용하지 않는 구성요소(예: `Text`)에 맞춤 `TransformationSpec`을 사용합니다.
다음 애니메이션은 목록 요소가 화면 상단과 하단에 접근할 때 크기가 조정되고 모양이 변경되는 방식을 보여줍니다.
다음 코드 스니펫은TransformingLazyColumn 레이아웃을 사용하여
다양한 Wear OS 화면 크기에서 멋지게 보이는 콘텐츠를 만드는 방법을 보여줍니다.
이 스니펫은 목록 항목에 설정하여 목록의 상단과 하단에 올바른 패딩을 적용해야 하는 minimumVerticalContentPadding 수정자의 사용법도 보여줍니다.
스크롤 표시기를 표시하려면 ScreenScaffold와 TransformingLazyColumn 간에 columnState를 공유합니다.
val columnState = rememberTransformingLazyColumnState() val transformationSpec = rememberTransformationSpec() ScreenScaffold( scrollState = columnState ) { contentPadding -> TransformingLazyColumn( state = columnState, contentPadding = contentPadding ) { item { ListHeader( modifier = Modifier .fillMaxWidth() .transformedHeight(this, transformationSpec) .minimumVerticalContentPadding(ListHeaderDefaults.minimumTopListContentPadding), transformation = SurfaceTransformation(transformationSpec) ) { Text(text = "Header") } } // ... other items item { Button( modifier = Modifier .fillMaxWidth() .transformedHeight(this, transformationSpec) .minimumVerticalContentPadding(ButtonDefaults.minimumVerticalListContentPadding), transformation = SurfaceTransformation(transformationSpec), onClick = { /* ... */ }, icon = { Icon( imageVector = Icons.Default.Build, contentDescription = "build", ) }, ) { Text( text = "Build", maxLines = 1, overflow = TextOverflow.Ellipsis, ) } } } }
맞추기 및 플링 효과 추가
맞추기를 사용하면 사용자가 스크롤 또는 플링 동작을 완료할 때 목록이 특정 지점(일반적으로 화면 중앙)에 정확하게 배치된 항목으로 정렬됩니다. 항목이 중앙에서 멀어질수록 크기가 조정되고 모핑되는 원형 화면에서 맞추기는 가장 관련성 높은 항목이 최적의 시청 영역에서 완전히 표시되고 읽을 수 있도록 하는 데 특히 유용합니다.맞추기 및 플링 동작을 추가하려면 flingBehavior 매개변수를 TransformingLazyColumnDefaults.snapFlingBehavior(columnState)로 설정합니다.
실제 크라운 또는 베젤을 사용할 때 일관된 환경을 제공하려면 rotaryScrollableBehavior를 RotaryScrollableDefaults.snapBehavior(columnState)를 사용하여 일치하도록 설정합니다.
val columnState = rememberTransformingLazyColumnState() ScreenScaffold(scrollState = columnState) { contentPadding -> TransformingLazyColumn( state = columnState, flingBehavior = TransformingLazyColumnDefaults.snapFlingBehavior(columnState), rotaryScrollableBehavior = RotaryScrollableDefaults.snapBehavior(columnState) ) { // ... // ... } }
레이아웃 반전
기본적으로 스크롤 가능한 목록은 상단 가장자리에 고정됩니다. 사용자가 표준 목록의 하단으로 스크롤하고 새 항목이 끝에 추가되면 목록은 현재 항목에 대한 사용자 뷰를 유지합니다. 예를 들어 사용자가 화면 하단에서 항목 10을 보고 있고 항목 11이 추가되면 뷰는 항목 10에 계속 집중되고 항목 11은 현재 뷰 아래의 화면 밖에 표시됩니다.
메시지 애플리케이션 또는 실시간 로그와 같은 사용 사례에서는 이 동작이 일반적으로 바람직하지 않습니다. 새 항목이 도착하면 사용자는 이미 목록 하단에 있는 경우 최신 콘텐츠를 즉시 보고 싶어 합니다. 한 번에 많은 항목이 도착하면 목록은 하단에 가장 최신 항목을 표시하도록 건너뛰어야 합니다. 즉, 사용자가 다시 위로 스크롤하지 않는 한 일부 중간 항목이 전혀 표시되지 않을 수 있습니다.
이러한 사용 사례를 지원하기 위해 TransformingLazyColumn을 사용하면 reverseLayout = true를 설정하여 레이아웃을 반전할 수 있습니다. 이렇게 하면 목록의 앵커가 상단 가장자리에서 하단 가장자리로 변경됩니다.
편의를 위해 reverseLayout = true를 설정하면 항목의 시각적 순서와 스크롤 동작의 방향도 반전됩니다.
- 항목은 하단에서 상단으로 구성됩니다. 즉, 색인 0이 화면 하단에 표시됩니다.
- 위로 스크롤하면 색인이 더 높은 항목이 표시됩니다.
레이아웃 반전과 함께 맞추기 및 플링 동작을 추가하려면 다음 스니펫과 같이 flingBehavior와 rotaryScrollableBehavior를 결합하면 됩니다.
val columnState = rememberTransformingLazyColumnState() val transformationSpec = rememberTransformationSpec() ScreenScaffold(scrollState = columnState) { contentPadding -> TransformingLazyColumn( state = columnState, contentPadding = contentPadding, reverseLayout = true, modifier = Modifier.fillMaxWidth() ) { items(10) { index -> Button( label = { Text( text = "Item ${index + 1}" ) }, onClick = {}, modifier = Modifier .fillMaxWidth() .transformedHeight(this, transformationSpec) .minimumVerticalContentPadding(ButtonDefaults.minimumVerticalListContentPadding), transformation = SurfaceTransformation(transformationSpec) ) } item { // With reverseLayout = true, the last item declared appears at the top. ListHeader( modifier = Modifier .fillMaxWidth() .transformedHeight(this, transformationSpec) .minimumVerticalContentPadding(ListHeaderDefaults.minimumTopListContentPadding), transformation = SurfaceTransformation(transformationSpec) ) { Text("Header") } } } }
다음 이미지는 일반 목록과 반전된 목록의 차이점을 보여줍니다.
목록의 가장자리 버튼
Material 3의 경우 목록 하단에 가장자리에 붙어 있는 버튼인 EdgeButton을 추가할 수 있습니다. 하지만 TransformingLazyColumn 내에 항목으로 추가하지 말고 ScreenScaffold의 edgeButton 슬롯을 사용해야 합니다.
edgeButton 슬롯을 사용하면 버튼이 화면 하단에 올바르게 배치되고 목록이 스크롤될 때 적절하게 동작합니다.
다음 코드 스니펫은 EdgeButton을 구현하는 방법을 보여줍니다.
val columnState = rememberTransformingLazyColumnState() ScreenScaffold( scrollState = columnState, edgeButton = { EdgeButton( onClick = { /* TODO */ }, modifier = Modifier.scrollable( columnState, orientation = Orientation.Vertical, reverseDirection = true, // Apply overscroll to the EdgeButton for proper scrolling behavior. overscrollEffect = rememberOverscrollEffect(), ) ) { Text("More") } } ) { contentPadding -> TransformingLazyColumn( contentPadding = contentPadding, state = columnState, ) { // ... // ... } }
목록의 SwipeToReveal
SwipeToReveal 구성요소를 사용하면 스와이프하여 Card 또는 Chip과 같은 목록 항목의 작업에 액세스할 수 있습니다. 스와이프하면 일반적으로 측면에서 하나 또는 두 개의 작업 버튼 (예: '삭제' 또는 '더보기')이 표시됩니다.
TransformingLazyColumn 내에서 SwipeToReveal을 사용하는 경우 다음 가이드라인을 따르세요.
- 스크롤 시 재설정: 사용자가 목록을 스크롤할 때 스와이프로 열린 항목을 덮인 상태로 재설정합니다.
- 일관된 높이: 일관된 모양을 보장하려면 작업 버튼 높이를 내부
스와이프 항목 (
Button또는Card)과 일치하도록 설정합니다. - 컨테이너 변환:
transformedHeight수정자와transformationSpec을SwipeToReveal구성요소 자체에 적용합니다. - 이중 변환하지 않음: 내부 스와이프 항목 (`SwipeToReveal`
SwipeToReveal컨테이너 내부의 카드 또는 버튼)에transformedHeight또는transformation수정자를 적용하지 마세요.
추천 서비스
- 참고: JavaScript가 사용 중지되어 있으면 링크 텍스트가 표시됩니다.
- Wear OS용 Compose Codelab
- 목록 및 그리드
- Compose에서 뷰 사용