Paging 3은 이전 Paging 라이브러리 버전과 크게 다릅니다. 이 버전은 Paging 2 사용 시 겪는 일반적인 어려움을 해결하고 기능을 향상했습니다. 앱이 이미 이전 버전의 Paging 라이브러리를 사용하는 경우 이 페이지를 참고하여 Paging 3으로 이전하는 방법을 자세히 알아보세요.
Paging 3이 앱에서 사용하는 첫 Paging 라이브러리 버전인 경우에는 페이징된 데이터 로드 및 표시에서 기본 사용법 정보를 확인하세요.
Paging 3으로 이전하여 얻을 수 있는 이점
Paging 3에는 이전 버전의 라이브러리에 없는 다음 기능이 포함되어 있습니다.
- Kotlin 코루틴 및 Flow를 위한 최고 수준의 지원 제공
- RxJava
Single
또는 GuavaListenableFuture
프리미티브를 사용한 비동기 로드 지원 - 재시도 및 새로고침 기능을 포함하여 반응형 UI 디자인을 위한 로드 상태와 오류 신호가 내장됨
- 취소 지원 및 간소화된 데이터 소스 인터페이스를 포함하여 저장소 레이어가 개선됨
- 프레젠테이션 레이어, 목록 구분자, 맞춤 페이지 변환, 로드 상태 머리글 및 바닥글이 개선됨
Paging 3으로 앱 이전
Paging 3으로 완전히 이전하려면 Paging 2의 세 가지 주요 구성요소를 모두 이전해야 합니다.
DataSource
클래스PagedList
PagedListAdapter
그러나 Paging 3의 일부 구성요소는 이전 버전의 Paging과 호환됩니다. 특히 Paging 3의 PagingSource
API는 이전 버전의 LivePagedListBuilder
및 RxPagedListBuilder
를 위한 데이터 소스가 될 수 있습니다. 마찬가지로 Pager
API는 asPagingSourceFactory()
메서드에 이전 DataSource
객체를 사용할 수 있습니다. 즉, 다음과 같은 이전 옵션이 있습니다.
DataSource
를PagingSource
로 이전하되 Paging 구현의 나머지 부분은 변경하지 않고 그대로 유지할 수 있습니다.PagedList
및PagedListAdapter
를 이전하되 이전DataSource
API를 계속 사용할 수 있습니다.- 전체 Paging 구현을 이전하여 앱을 Paging 3으로 완전히 이전할 수 있습니다.
이 페이지의 섹션에서는 앱의 각 레이어에서 Paging 구성요소를 이전하는 방법을 설명합니다.
DataSource 클래스
이 섹션에서는 PagingSource
를 사용하기 위해 이전 Paging 구현을 이전하는 데 필요한 변경사항을 모두 설명합니다.
Paging 2의 PageKeyedDataSource
, PositionalDataSource
, ItemKeyedDataSource
가 모두 Paging 3의 PagingSource
API로 결합됩니다. 모든 이전 API 클래스의 로드 메서드는 PagingSource
에서 단일 load()
메서드로 결합됩니다. 이전 API 클래스의 구현에서는 여러 로드 메서드에서 많은 로직이 동일한 경우가 많기 때문에, 단일 메서드로 결합됨으로써 코드 중복이 줄어듭니다.
모든 로드 메서드 매개변수는 Paging 3에서 각 로드 유형의 서브클래스를 포함하는 LoadParams
봉인 클래스로 대체됩니다. load()
메서드에서 로드 유형을 구별해야 하는 경우 어떤 LoadParams
서브클래스(LoadParams.Refresh
, LoadParams.Prepend
, LoadParams.Append
)가 전달되었는지 확인하세요.
PagingSource
구현에 관한 자세한 내용은 데이터 소스 정의를 참고하세요.
새로고침 키
PagingSource
의 구현은 로드된 페이지된 데이터의 중간에서 새로고침을 다시 시작하는 방법을 정의해야 합니다. state.anchorPosition
을 최근에 액세스한 색인으로 사용하여 정확한 초기 키를 매핑하기 위해 getRefreshKey()
를 구현하면 됩니다.
Kotlin
// Replaces ItemKeyedDataSource. override fun getRefreshKey(state: PagingState): String? { return state.anchorPosition?.let { anchorPosition -> state.getClosestItemToPosition(anchorPosition)?.id } } // Replacing PositionalDataSource. override fun getRefreshKey(state: PagingState ): Int? { return state.anchorPosition }
Java
// Replaces ItemKeyedDataSource. @Nullable @Override String getRefreshKey(state: PagingState) { Integer anchorPosition = state.anchorPosition; if (anchorPosition == null) { return null; } return state.getClosestItemToPosition(anchorPosition); } // Replaces PositionalDataSource. @Nullable @Override Integer getRefreshKey(state: PagingState ) { return state.anchorPosition; }
Java
// Replacing ItemKeyedDataSource. @Nullable @Override String getRefreshKey(state: PagingState) { Integer anchorPosition = state.anchorPosition; if (anchorPosition == null) { return null; } return state.getClosestItemToPosition(anchorPosition); } // Replacing PositionalDataSource. @Nullable @Override Integer getRefreshKey(state: PagingState ) { return state.anchorPosition; }
목록 변환
이전 버전의 Paging 라이브러리에서는 페이징된 데이터를 변환하는 데 다음 메서드를 사용합니다.
DataSource.map()
DataSource.mapByPage()
DataSource.Factory.map()
DataSource.Factory.mapByPage()
Paging 3에서는 모든 변환이 PagingData
의 연산자로 적용됩니다. 위의 목록에 있는 메서드를 사용하여 페이징된 목록을 변환하는 경우에는 새로운 PagingSource
를 사용하여 Pager
를 구성할 때 변환 로직을 DataSource
에서 PagingData
로 이동해야 합니다.
Paging 3을 사용하여 페이징된 데이터에 변환을 적용하는 방법을 자세히 알아보려면 데이터 스트림 변환을 참고하세요.
PagedList
이 섹션에서는 Paging 3에서 Pager
및 PagingData
를 사용하기 위해 이전 Paging 구현을 이전하는 데 필요한 변경사항을 모두 설명합니다.
PagedListBuilder 클래스
PagingData
는 Paging 2의 기존 PagedList
를 대체합니다. PagingData
로 이전하려면 다음을 업데이트해야 합니다.
- 페이징 구성이
PagedList.Config
에서PagingConfig
로 이동했습니다. LivePagedListBuilder
및RxPagedListBuilder
가 단일Pager
클래스로 결합되었습니다.Pager
는.flow
속성을 사용하여 관찰 가능한Flow<PagingData>
를 노출합니다. RxJava 및 LiveData 변형도 확장 속성으로 사용할 수 있으며 정적 메서드를 통해 Java에서 호출할 수 있고 각각paging-rxjava*
모듈과paging-runtime
모듈에서 제공됩니다.
Kotlin
val flow = Pager( // Configure how data is loaded by passing additional properties to // PagingConfig, such as prefetchDistance. PagingConfig(pageSize = 20) ) { ExamplePagingSource(backend, query) }.flow .cachedIn(viewModelScope)
Java
// CoroutineScope helper provided by the lifecycle-viewmodel-ktx artifact. CoroutineScope viewModelScope = ViewModelKt.getViewModelScope(viewModel); Pager<Integer, User> pager = Pager<>( new PagingConfig(/* pageSize = */ 20), () -> ExamplePagingSource(backend, query)); Flowable<PagingData<User>> flowable = PagingRx.getFlowable(pager); PagingRx.cachedIn(flowable, viewModelScope);
Java
// CoroutineScope helper provided by the lifecycle-viewmodel-ktx artifact. CoroutineScope viewModelScope = ViewModelKt.getViewModelScope(viewModel); Pager<Integer, User> pager = Pager<>( new PagingConfig(/* pageSize = */ 20), () -> ExamplePagingSource(backend, query)); PagingLiveData.cachedIn(PagingLiveData.getLiveData(pager), viewModelScope);
Paging 3을 사용하여 PagingData
객체의 반응형 스트림을 설정하는 방법에 관한 자세한 내용은 PagingData 스트림 설정을 참고하세요.
계층화된 소스용 BoundaryCallback
Paging 3에서는 RemoteMediator
가 PagedList.BoundaryCallback
을 대체하여 네트워크 및 데이터베이스에서 페이징하기 위한 핸들러로 사용됩니다.
Paging 3에서 RemoteMediator
를 사용하여 네트워크 및 데이터베이스에서 페이징하는 방법에 관해 자세히 알아보려면 Android Paging Codelab을 참고하세요.
PagedListAdapter
이 섹션에서는 Paging 3의 PagingDataAdapter
또는 AsyncPagingDataDiffer
클래스를 사용하기 위해 이전 Paging 구현을 이전하는 데 필요한 변경사항을 모두 설명합니다.
Paging 3은 새로운 PagingData
반응형 스트림을 처리하기 위한 PagingDataAdapter
를 제공합니다. 그러지 않으면 PagedListAdapter
와 PagingDataAdapter
의 인터페이스가 동일합니다. PagedListAdapter
에서 PagingDataAdapter
로 이전하려면 PagingDataAdapter
를 대신 확장하도록 PagedListAdapter
의 구현을 변경합니다.
PagingDataAdapter
에 관한 자세한 내용은 RecyclerView 어댑터 정의를 참고하세요.
AsyncPagedListDiffer
현재 AsyncPagedListDiffer
가 적용된 맞춤 RecyclerView.Adapter
구현을 사용 중이라면 대신 Paging 3에서 제공되는 AsyncPagingDataDiffer
를 사용하도록 구현을 이전하세요.
Kotlin
AsyncPagingDataDiffer(diffCallback, listUpdateCallback)
Java
new AsyncPagingDataDiffer(diffCallback, listUpdateCallback);
Java
new AsyncPagingDataDiffer(diffCallback, listUpdateCallback);
추가 리소스
Paging 라이브러리에 관한 자세한 내용은 다음과 같은 추가 리소스를 참고하세요.
Codelab
샘플
추천 서비스
- 참고: JavaScript가 사용 중지되어 있으면 링크 텍스트가 표시됩니다.
- 페이징된 데이터 로드 및 표시
- 페이징된 데이터 수집
- 네트워크 및 데이터베이스의 페이지