💡 Paging ?
시스템 리소스를 효율적으로 활용하기 위해서 일정한 페이지 사이즈 만큼 나눠서 데이터를 로딩하는 기능.
1. PagingSource 구현
- pagingSource<Key, Value> : 키는 데이터를 로드하는데 사용되는 식별자, 값은 데이터 자체의 유형
- load() : params.key로 다음 페이지 값 전달
- LoadResult : 로드 작업에 대한 결과
class TicketPagingSource(
private val category: String?,
private val sort: Array<String>,
private val service: TicketApiService
) : PagingSource<Int, TicketDto>() {
override fun getRefreshKey(state: PagingState<Int, TicketDto>): Int? {
return state.anchorPosition?.let { anchorPosition ->
state.closestPageToPosition(anchorPosition)?.prevKey?.plus(1)
?: state.closestPageToPosition(anchorPosition)?.nextKey?.minus(1)
}
}
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, TicketDto> {
return try {
val next = params.key ?: 0
val response = service.getTickets(category, next, 1, "${sort[0]},${sort[1]}")
if (response.success && response.data.contents.isNotEmpty()) {
LoadResult.Page(
data = response.data.contents,
prevKey = null,
nextKey = if (response.data.nextPage == -1) null else next + 1
)
} else {
LoadResult.Page(
data = response.data.contents,
prevKey = null,
nextKey = null
)
}
} catch (e: Exception) {
LoadResult.Error(e)
}
}
}
2. PagingSource를 이용하여 flow 생성
- pageSize는 실제 서버에 요청하는 아이템 개수와 동일
class TicketRemoteDataSourceImpl @Inject constructor(
private val service: TicketApiService
) : TicketRemoteDataSource {
override fun getTicketsList(
category: String?,
size: Int,
sort: Array<String>
): Flow<PagingData<TicketDto>> =
Pager(
config = PagingConfig(pageSize = size, enablePlaceholders = false),
pagingSourceFactory = {
TicketPagingSource(category = category, sort = sort, service)
}
).flow
}
3. viewModel 에서 호출하기
fun requestTickets(): Flow<PagingData<Ticket>> {
return ticketsUseCase.getTickets(
ticketCategory.value,
1,
when(ticketSort.value) {
LATEST -> arrayOf(CREATED_AT, DESC)
OLDEST ->arrayOf(CREATED_AT, ASC)
HIGH_SCORE ->arrayOf(RATING, DESC)
LOW_SCORE ->arrayOf(RATING, ASC)
else -> emptyArray()
}
)
.cachedIn(viewModelScope)
}
4.
'안드로이드' 카테고리의 다른 글
[안드로이드] Hilt - 1 (0) | 2022.10.13 |
---|---|
[안드로이드] 코루틴 - Scope, Dispacher (0) | 2022.10.12 |
[안드로이드] Activity vs Fragment 차이 (0) | 2022.10.09 |
[안드로이드] ViewBinding 사용시 주의점 (0) | 2022.10.07 |
[코틀린] Coroutine Flow 개념 정리 (0) | 2022.10.06 |