LazyRow — 는 Jetpack Compose에서 요소를 지연 로딩하는 가로 목록을 만들기 위한 컴포저블 함수입니다. Row와 달리 LazyRow는 보이는 요소만 생성하고 가로 스크롤 중에 이를 재사용합니다. Google Android Documentation, 2025에 따르면 LazyRow는 LazyColumn의 가로 버전이며 모바일 애플리케이션의 캐러셀, 갤러리 및 가로 메뉴에 효과적입니다.
핵심 포인트
LazyRow — 는 요소를 지연 로딩하는 가로 스크롤 가능 목록을 구현하는 컴포저블 함수입니다. 모든 하위 요소를 동시에 렌더링하는 Row와 달리 LazyRow는 뷰포트에 보이는 요소만 생성합니다.
LazyRow는 LazyColumn과 동일한 원리로 작동하지만 요소를 가로로 배치합니다. 왼쪽이나 오른쪽으로 스크롤하면 뷰포트를 벗어난 요소가 재사용되어 새 요소를 표시합니다. 이는 많은 이미지가 있는 갤러리나 긴 카테고리 목록에 매우 중요합니다.
Android Developers Blog, 2024에 따르면 LazyRow는 LazyColumn과 동일한 LazyList 아키텍처를 사용하며, 여기에는 LazyListState, Pool을 통한 재사용 메커니즘 및 다양한 요소 유형 지원이 포함됩니다. 최대 효율은 요소 높이를 고정하여 달성됩니다.
LazyRow는 modifier, state, contentPadding, reverseLayout, horizontalArrangement 및 verticalAlignment 매개변수를 허용합니다. 콘텐츠는 LazyColumn과 유사하게 DSL 함수 items 및 item을 통해 정의됩니다.
@Composable
fun SimpleLazyRow() {
val items = (1..50).toList()
LazyRow(
modifier = Modifier.fillMaxWidth().height(100.dp),
horizontalArrangement = Arrangement.spacedBy(8.dp),
contentPadding = PaddingValues(start = 16.dp, end = 16.dp)
) {
items(items) { item ->
Box(
modifier = Modifier.size(80.dp).background(Color.Gray)
) {
Text(text = "$item", modifier = Modifier.align(Alignment.Center))
}
}
}
}
horizontalArrangement는 LazyRow 내 가로 축을 따라 요소의 분포를 관리합니다. Row와 동일한 Arrangement 값을 사용할 수 있습니다: Start, Center, End, SpaceBetween, SpaceEvenly, SpaceAround 및 사용자 정의 간격의 spacedBy.
contentPadding은 LazyRow 컨테이너 가장자리에 패딩을 추가합니다. Modifier.padding과 달리 contentPadding은 스크롤 시 고려됩니다. 첫 번째 요소는 왼쪽 가장자리에서, 마지막 요소는 오른쪽 가장자리에서 패딩이 적용됩니다. Material Design Guidelines, 2025에 따르면 캐러셀과 갤러리에서 첫 번째와 마지막 요소가 화면 가장자리에 붙지 않도록 contentPadding이 필수입니다.
verticalAlignment는 LazyRow 내에서 요소를 세로로 정렬합니다. 기본적으로 Alignment.Top이 사용됩니다. 높이가 다른 요소를 중앙에 배치하려면 Alignment.CenterVertically를 사용하세요. 이는 다양한 종횡비의 이미지가 있는 캐러셀에 유용합니다.
| 매개변수 | 설명 | 기본값 |
|---|---|---|
| horizontalArrangement | 요소의 가로 분포 | Arrangement.Start |
| contentPadding | 컨테이너 가장자리 패딩 | PaddingValues(0.dp) |
| verticalAlignment | 세로 정렬 | Alignment.Top |
| reverseLayout | 요소 순서 반전 | false |
| userScrollEnabled | 사용자 스크롤 활성화 | true |
LazyListState는 LazyRow의 경우 LazyColumn과 동일하게 작동합니다. 첫 번째 보이는 요소, 오프셋 및 전체 스크롤 위치를 추적합니다. 상태는 rememberLazyListState()를 통해 생성되고 state 매개변수에 전달됩니다.
LazyRow의 프로그래밍 방식 스크롤 제어는 동일한 메서드로 수행됩니다. 부드러운 애니메이션에는 animateScrollToItem, 즉시 스크롤에는 scrollToItem을 사용합니다. 둘 다 코루틴 내에서 호출됩니다. 이는 좌우 버튼이 있는 캐러셀이나 자동 스크롤에 유용합니다.
Android Developers, 2024에 따르면 LazyRow는 SnapFlingBehavior도 지원합니다 — 요소 사이가 아닌 가장 가까운 요소에서 멈추는 빠른 스크롤 동작입니다. 이는 캐러셀과 갤러리에 익숙한 스냅 효과를 만듭니다.
@Composable
fun CarouselWithSnap() {
val listState = rememberLazyListState()
val scope = rememberCoroutineScope()
val items = listOf("A", "B", "C", "D", "E")
Column {
LazyRow(
state = listState,
flingBehavior = SnapFlingBehavior(listState),
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
items(items) { item ->
Card(modifier = Modifier.width(150.dp)) {
Text(text = item, modifier = Modifier.padding(16.dp))
}
}
}
Row(modifier = Modifier.fillMaxWidth()) {
Button(onClick = {
scope.launch {
listState.animateScrollToItem(0)
}
}) { Text("시작하려면") }
}
}
}
첫 번째 예시 — 미리보기가 있는 이미지 갤러리를 위한 LazyRow입니다. 각 요소는 이미지와 캡션이 있는 Box입니다. LazyRow는 수십 및 수백 개의 이미지를 효율적으로 처리하며 보이는 이미지만 로드합니다.
@Composable
fun ImageGallery(images: List<String>) {
LazyRow(
contentPadding = PaddingValues(start = 16.dp, end = 16.dp),
horizontalArrangement = Arrangement.spacedBy(12.dp)
) {
items(images, key = { it }) { url ->
AsyncImage(
model = url,
contentDescription = "Image",
modifier = Modifier.size(120.dp)
)
}
}
}
두 번째 예시 — 아이콘이 있는 카테고리 목록을 위한 LazyRow입니다. 카테고리는 칩으로 표시되며 사용자가 가로로 스크롤할 수 있습니다. spacedBy 및 contentPadding이 있는 LazyRow는 카테고리 사이와 가장자리에 간격을 만듭니다.
@Composable
fun CategoryChips(categories: List<String>) {
LazyRow(
contentPadding = PaddingValues(horizontal = 16.dp),
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
items(categories, key = { it }) { category ->
AssistChip(
onClick = {},
label = { Text(category) }
)
}
}
}
LazyRow와 Row의 선택은 요소 수에 따라 다릅니다. Row는 항상 화면에 표시되는 5–10개의 요소에 적합합니다. LazyRow는 요소가 많거나 개수가 동적일 때 필요합니다.
Row는 모든 요소를 한 번에 렌더링하므로 요소 수가 많을 때 지연이 발생합니다. LazyRow는 보이는 요소만 렌더링하므로 스크롤 가능한 목록에 선호됩니다. Android Developers Blog, 2024에 따르면 임계값은 약 10개 요소입니다. 더 많은 요소가 있으면 LazyRow를 사용하세요.
LazyRow는 애니메이션, SnapFlingBehavior 및 구분자를 통한 그룹화도 지원하여 복잡한 인터페이스에 더 유연합니다. Row는 더 간단하고 LazyListState가 필요하지 않지만 긴 목록에 최적화되어 있지 않습니다.
자주 묻는 질문
LazyRow는 가로로 스크롤되며 요소를 왼쪽에서 오른쪽으로 배치하고, LazyColumn은 세로로 위에서 아래로 스크롤됩니다. 둘 다 동일한 지연 로딩 원칙, LazyListState 및 DSL items 함수를 사용합니다.
SnapFlingBehavior(listState)를 LazyRow의 flingBehavior 매개변수에 전달하세요. SnapFlingBehavior는 LazyRow가 요소 사이가 아닌 가장 가까운 요소에서 멈추도록 하여 캐러셀용 스냅 효과를 만듭니다.
LazyListState.layoutInfo를 통해 마지막 보이는 요소를 추적하고 마지막 요소가 목록 끝에 가까워지면 새 데이터를 로드하세요. 순환 스크롤의 경우 요소 복제와 함께 사용자 정의 구현을 사용하세요.
네, LazyRow는 LazyColumn 내에 중첩될 수 있습니다. 이는 세로 목록 내에 가로 캐러셀이 있는 복잡한 페이지를 만드는 표준 패턴입니다. 올바른 작동을 위해 각 LazyRow는 고정 높이를 가져야 합니다.
LazyListState.layoutInfo.visibleItemsInfo를 사용하고 마지막 보이는 요소의 인덱스를 총 개수에서 1을 뺀 값과 비교하세요. 이 값이 일치하면 LazyRow가 목록 끝에 있습니다.
요약
턴키 방식의 모바일 애플리케이션을 개발해 드립니다
IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.