본문 바로가기
Android (Kotlin & Compose)/Part 2. Jetpack Compose UI

[오늘의 코드 조각] [2-3] 더 긴 목록 보여주기: 리사이클러뷰 대신 LazyColumn

by 생각하는 개발자님 2025. 12. 22.
반응형

안녕하세요, '생각하는 개발자'입니다.

인스타그램의 피드, 카카오톡의 채팅 목록, 유튜브의 동영상 리스트... 우리가 매일 쓰는 앱들은 수많은 데이터를 목록 형태로 보여줍니다.

과거 안드로이드에서는 이런 목록을 만들기 위해 Adapter, ViewHolder 등 복잡한 코드를 잔뜩 작성해야 했습니다. 하지만 Jetpack Compose에서는 이름부터 재미있는 LazyColumn 하나로 이 모든 과정을 혁신적으로 줄였습니다.

 

1. 왜 그냥 Column이 아니라 'Lazy'인가요?

Column은 안에 100개의 아이템이 있다면, 화면에 보이든 안 보이든 100개를 한꺼번에 다 그려버립니다. 데이터가 많아지면 앱이 버벅거리겠죠?

제트팩 컴포즈의 LazyColumn을 사용하여 효율적인 무한 스크롤 목록을 만드는 방법 설명 이미지


**LazyColumn**은 이름처럼 '게으르게' 작동합니다. 지금 화면에 보이는 아이템만 그리고, 나머지는 스크롤을 내릴 때 그때그때 그립니다. 덕분에 데이터가 10,000개라도 앱은 아주 매끄럽게 돌아갑니다.

 

2. 실전 예제: LazyListPractice.kt

안드로이드 스튜디오에서 바로 실행해볼 수 있는 코드를 준비했습니다. LazyListPractice.kt 파일을 만들고 아래 코드를 넣어보세요.

 

package com.example.composepractice.ch2_3_list

import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material3.*
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp

// 1. 데이터 모델 정의 (책에 들어갈 실무적인 구조)
data class Fruit(val name: String, val price: String)

@Composable
fun LazyListScreen() {
    // 2. 보여줄 데이터 리스트 준비
    val fruitList = listOf(
        Fruit("사과", "1,000원"),
        Fruit("바나나", "2,500원"),
        Fruit("포도", "5,000원"),
        Fruit("수박", "15,000원"),
        Fruit("딸기", "8,000원"),
        Fruit("멜론", "12,000원"),
        Fruit("오렌지", "3,000원")
    )

    // 3. LazyColumn으로 목록 구현
    LazyColumn(
        modifier = Modifier.fillMaxSize(),
        contentPadding = PaddingValues(16.dp), // 리스트 전체의 여백
        verticalArrangement = Arrangement.spacedBy(8.dp) // 아이템 사이의 간격
    ) {
        item {
            Text(text = "오늘의 과일 장터", fontSize = 24.sp, modifier = Modifier.padding(bottom = 16.dp))
        }

        // 4. items 함수를 사용해 데이터 리스트를 하나씩 그리기
        items(fruitList) { fruit ->
            FruitItemCard(fruit = fruit)
        }
    }
}

@Composable
fun FruitItemCard(fruit: Fruit) {
    Card(
        modifier = Modifier.fillMaxWidth(),
        elevation = CardDefaults.cardElevation(defaultElevation = 2.dp)
    ) {
        Row(
            modifier = Modifier
                .padding(16.dp)
                .fillMaxWidth(),
            horizontalArrangement = Arrangement.SpaceBetween
        ) {
            Text(text = fruit.name, fontSize = 18.sp)
            Text(text = fruit.price, color = MaterialTheme.colorScheme.primary)
        }
    }
}

@Preview(showBackground = true)
@Composable
fun LazyListPreview() {
    LazyListScreen()
}

package com.example.composepractice.ch2_3_list

import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material3.*
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp

// 1. 데이터 모델 정의 (책에 들어갈 실무적인 구조)
data class Fruit(val name: String, val price: String)

@Composable
fun LazyListScreen() {
    // 2. 보여줄 데이터 리스트 준비
    val fruitList = listOf(
        Fruit("사과", "1,000원"),
        Fruit("바나나", "2,500원"),
        Fruit("포도", "5,000원"),
        Fruit("수박", "15,000원"),
        Fruit("딸기", "8,000원"),
        Fruit("멜론", "12,000원"),
        Fruit("오렌지", "3,000원")
    )

    // 3. LazyColumn으로 목록 구현
    LazyColumn(
        modifier = Modifier.fillMaxSize(),
        contentPadding = PaddingValues(16.dp), // 리스트 전체의 여백
        verticalArrangement = Arrangement.spacedBy(8.dp) // 아이템 사이의 간격
    ) {
        item {
            Text(text = "오늘의 과일 장터", fontSize = 24.sp, modifier = Modifier.padding(bottom = 16.dp))
        }

        // 4. items 함수를 사용해 데이터 리스트를 하나씩 그리기
        items(fruitList) { fruit ->
            FruitItemCard(fruit = fruit)
        }
    }
}

@Composable
fun FruitItemCard(fruit: Fruit) {
    Card(
        modifier = Modifier.fillMaxWidth(),
        elevation = CardDefaults.cardElevation(defaultElevation = 2.dp)
    ) {
        Row(
            modifier = Modifier
                .padding(16.dp)
                .fillMaxWidth(),
            horizontalArrangement = Arrangement.SpaceBetween
        ) {
            Text(text = fruit.name, fontSize = 18.sp)
            Text(text = fruit.price, color = MaterialTheme.colorScheme.primary)
        }
    }
}

@Preview(showBackground = true)
@Composable
fun LazyListPreview() {
    LazyListScreen()
}

 

3. 핵심 포인트 요약

items(리스트): 리스트 데이터를 통째로 넘기면 자동으로 반복하며 그려줍니다.
contentPadding: 리스트 상하좌우에 여백을 줄 때 사용합니다.
verticalArrangement = Arrangement.spacedBy(): 아이템 사이사이에 간격을 줄 때 아주 편리합니다.

 

다음 단계 예고
이제 목록까지 만들 줄 알게 되었습니다! 하지만 앱이라면 목록의 아이템을 클릭했을 때 다음 화면으로 넘어가야겠죠?

다음 포스팅에서는 [2-4] 화면 이동하기: Compose Navigation 기초를 다뤄볼까요? 원하신다면 바로 진행해 드리겠습니다.

 

반응형