컴파일 오류를 해결하기 전에 ViewModel을 살펴보겠다.
class ArticleViewModel(...) : ViewModel() {
val items: StateFlow<List<Article>> = ...
}
ViewModel에 Paging 라이브러리를 통합하기 위해 items의 반환 유형을 StateFlow<List<Ariticle>>에서 Flow<PagingData<Article>>로 변경한다. 이렇게 하려면 먼저 ITEMS_PER_PAGE라는 비공개 상수를 파일 상단에 추가한다.
private const val ITEMS_PER_PAGE = 50
class ArticleViewModel {
...
}
다음으로 Pager 인스턴스의 출력 결과가 되도록 items를 업데이트한다. Pager에 매개변수 두 개를 전달하면 된다.
- pageSize가 ITEMS_PER_PAGE이고 자리표시자가 사용 중지된 PagingConfig
- 방금 만든 ArticlePagingSource의 인스턴스를 제공하는 PagingSourceFactory
class ArticleViewModel(...) : ViewModel() {
val items: Flow<PagingData<Article>> = Pager(
config = PagingConfig(pageSize = ITEMS_PER_PAGE, enablePlaceholders = false),
pagingSourceFactory = { repository.articlePagingSource() }
)
.flow
...
}
※ pagingSourceFactory 람다는 PagingSource 인스턴스를 재사용할 수 없으므로 호출되는 경우 항상 완전히 새로운 PagingSource를 반환해야 한다.
이제 구성 또는 탐색 변경사항에도 페이징 상태를 유지하려면 androidx.lifecycle.viewModelScope를 전달하는 cachedIn() 메소드를 활용한다.
※ PagingData Flow와 함께 stateIn() 또는 sharedIn() 연산자를 사용하면 안 된다. PagingData Flow는 콜드 상태가 아니다. Flow에서 map 또는 filter와 같은 작업을 실행하는 경우 작업을 실행한 후 cachedIn을 호출하여 작업을 다시 트리거할 필요가 없도록 해야 한다. 즉, 터미널 연산자로 cachedIn을 사용해야 한다.
위 변경을 완료하면 ViewModel이 다음과 같이 표시된다.
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.PagingData
import androidx.paging.cachedIn
import com.example.android.codelabs.paging.data.Article
import com.example.android.codelabs.paging.data.ArticleRepository
import com.example.android.codelabs.paging.data.ITEMS_PER_PAGE
import kotlinx.coroutines.flow.Flow
private const val ITEMS_PER_PAGE = 50
class ArticleViewModel(
private val repository: ArticleRepository,
) : ViewModel() {
val items: Flow<PagingData<Article>> = Pager(
config = PagingConfig(pageSize = ITEMS_PER_PAGE, enablePlaceholders = false),
pagingSourceFactory = { repository.articlePagingSource() }
)
.flow
.cachedIn(viewModelScope)
}
PagingData의 또 다른 유의 사항은 RecyclerView에 표시할 데이터에 관한 변경 가능한 업데이트 스트림이 포함된 독립적인 유형이라는 것이다. 각 PagingData 내보내기는 완전히 독립적이며 지원 PagingSource가 기본 데이터 세트 변경으로 인해 무효화되는 경우 간일 쿼리에 관해 여러 PagingData 인스턴스를 내보낼 수 있다. 따라서 PagingData의 Flows는 다른 Flows와 독립적으로 노출되어야 한다.
※ PagingData Flow를 다른 Flows와 함께 사용하거나 결합하지 않아야 한다. 내보낸 PagingData는 각각 독립적으로 사용되어야 한다. 또한, sharedIn 및 stateIn 같은 연산자를 PagingData Flows에 사용해서는 안 된다.
'Kotlin' 카테고리의 다른 글
[Paging] UI에서 PagingData 사용 (0) | 2023.02.20 |
---|---|
[Paging] PagingData를 사용하도록 어댑터 설정 (0) | 2023.02.20 |
[Paging] UI용 PagingData 생성 (0) | 2023.02.07 |
[Paging] Paging 사용법 (0) | 2023.02.05 |
[Paging] Paging이란? (0) | 2023.02.03 |
댓글