본문 바로가기
안드로이드 코틀린

[Kotlin][Android] Jetpack Compose 의 LazyPagingItems 사용하여 아이템 페이징 하기

by teamnova 2024. 12. 27.
728x90

 

안녕하세요 오늘은 Jetpack Compos 의 LazyPagingItems 사용하여 아이템 페이징 기능을 구현해보도록 하겠습니다 

 

대량의 데이터를 한 번에 불러올 때, 페이징(Paging) 기법을 사용하여 필요한 데이터만 단계적으로 가져오는 것이 일반적입니다. 이렇게 하면 네트워크 사용량을 줄이고, 사용자에게 더 나은 성능과 부드러운 스크롤 경험을 제공할 수 있습니다.

 

 

 

1.ItemRepository.kt

class ItemRepository {
    fun getItems(): PagingSource<Int, String> {
        return object : PagingSource<Int, String>() {
            override suspend fun load(params: LoadParams<Int>): LoadResult<Int, String> {
                val page = params.key ?: 1
                val items = (1..20).map { "Item #$it from Page $page" }

                return LoadResult.Page(
                    data = items,
                    prevKey = if (page == 1) null else page - 1,
                    nextKey = if (items.isNotEmpty()) page + 1 else null
                )
            }

            override fun getRefreshKey(state: PagingState<Int, String>): Int? {
                return state.anchorPosition?.let { anchorPosition ->
                    state.closestPageToPosition(anchorPosition)?.prevKey?.plus(1)
                        ?: state.closestPageToPosition(anchorPosition)?.nextKey?.minus(1)
                }
            }
        }
    }
}

 

데이터를 페이지 단위로 로드 (Data Source) 하는 역할을 합니다 

현재 아이템은 각 페이지마다 20개씩 불러옵니다. 

하드코딩 되어있기 때문에 데이터베이스에 연결해서 사용할 수 있습니다 

 

 

 

2. PagingViewModel.kt

class PagingViewModel : ViewModel() {
    private val repository = ItemRepository()

    val pager = Pager(
        config = PagingConfig(pageSize = 20)
    ) {
        repository.getItems()
    }.flow.cachedIn(viewModelScope)
}

 

Pager를 사용해 데이터를 Flow 형태로 관리합니다 

 

 

3. PagingListScreen.kt

@Composable
fun PagingListScreen(viewModel: PagingViewModel = viewModel()) {
    val items = viewModel.pager.collectAsLazyPagingItems()

    LazyColumn(
        modifier = Modifier.fillMaxSize(),
        verticalArrangement = Arrangement.spacedBy(8.dp)
    ) {
        items(items.itemCount) { index ->
            val item = items[index]
            if (item != null) {
                PagingItemCard(item)
            }
        }

        items.apply {
            when {
                loadState.refresh is LoadState.Loading -> {
                    item {
                        CircularProgressIndicator(modifier = Modifier.fillMaxWidth())
                    }
                }
                loadState.append is LoadState.Loading -> {
                    item {
                        CircularProgressIndicator(modifier = Modifier.fillMaxWidth())
                    }
                }
                loadState.refresh is LoadState.Error -> {
                    val error = (loadState.refresh as LoadState.Error).error
                    item {
                        Text("Error: ${error.localizedMessage}")
                    }
                }
            }
        }
    }
}

 

LazyPagingItems로 페이징 데이터 표시하는 역할을 합니다. 

 

 

마지막으로 메인 클래스 입니다 

4. MainActivity.kt

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            MaterialTheme {
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colorScheme.background
                ) {
                    PagingListScreen()
                }
            }
        }
    }
}

 

 

감사합니다