봄날은 갔다. 이제 그 정신으로 공부하자

Paging Library - Display paged lists 본문

Android jetpack

Paging Library - Display paged lists

길재의 그 정신으로 공부하자 2020. 11. 24. 14:40

이 글에서는 “Paging Library - Overview(als2019.tistory.com/8)”를 기반으로 특히 정보가 변경될 때 앱의 UI에서 사용자에게 정보 목록을 표시하는 방법을 설명합니다.

 

프로젝트에 Paging Library 추가

프로젝트의 build.gradle 파일에 아래 종속성을 추가합니다.

dependencies {
    def paging_version = "2.1.0"

    // For Kotlin use paging-runtime-ktx
    implementation "androidx.paging:paging-runtime:$paging_version" 

    // alternatively - without Android dependencies for testing
    // For Kotlin use paging-common-ktx
    testImplementation "androidx.paging:paging-common:$paging_version" 

    // optional - RxJava support
    // For Kotlin use paging-rxjava2-ktx
    implementation "androidx.paging:paging-rxjava2:$paging_version" 
}

 

뷰 모델에 UI 연결

아래 예제와 같이 LiveData<PagedList> 인스턴스를 PagedListAdapter에 연결할 수 있습니다.

private val adapter = ConcertAdapter()
private lateinit var viewModel: ConcertViewModel

override fun onCreate(savedInstanceState: Bundle?) {
    viewModel = ViewModelProviders.of(this).get(ConcertViewModel::class.java)
    viewModel.concerts.observe(this, Observer { adapter.submitList(it) })
}

Data Source가 새로운 PagedList 인스턴스를 제공할 때 활동은 개체를 어댑터로 보냅니다. 

PagedListAdapter 구현은 업데이트가 계산되는 방식을 정의하며 페이징 및 목록 디핑(Diffing)을 자동으로 처리합니다. 

따라서 ViewHolder는 아래와 같이 특정 항목에만 결합해야 합니다.

class ConcertAdapter() :
        PagedListAdapter<Concert, ConcertViewHolder>(DIFF_CALLBACK) {
    override fun onBindViewHolder(holder: ConcertViewHolder, position: Int) {
        val concert: Concert? = getItem(position)

        // Note that "concert" is a placeholder if it's null.
        holder.bindTo(concert)
    }

    companion object {
        private val DIFF_CALLBACK = ... // 아래 “Diffing Callback 구현” 참고.
    }
}

PagedListAdapter는 PagedList.Callback 개체를 사용하여 페이지 로드 이벤트를 처리합니다. 사용자가 스크롤함에 따라 PagedListAdapter는 PagedList.loadAround()를 호출하여 DataSource에서 가져와야 하는 항목에 관한 힌트를 기본 PagedList에 제공합니다.

 

& 참고 &

PagedList의 콘텐츠는 변경할 수 없습니다. 즉, 새 콘텐츠를 PagedList 인스턴스에 로드할 수 있지만 로드한 후에는 로드된 항목 자체를 변경할 수 없습니다. 따라서 PagedList의 콘텐츠가 업데이트되면 PagedListAdapter 개체는 업데이트된 정보가 포함된 완전히 새로운 PagedList를 받습니다.

 

Diffing Callback 구현

아래 예제는 동일한 Object인지 비교하는 areContentsTheSame() 함수입니다.

private val DIFF_CALLBACK = object : DiffUtil.ItemCallback<Concert>() {
    // The ID property identifies when items are the same.
    override fun areItemsTheSame(oldItem: Concert, newItem: Concert) =
            oldItem.id == newItem.id

    // If you use the "==" operator, make sure that the object implements
    // .equals(). Alternatively, write custom data comparison logic here.
    override fun areContentsTheSame(
            oldItem: Concert, newItem: Concert) = oldItem == newItem
}

Adapter에는 비교 항목의 정의가 포함되어 있으므로 새 PagedList 개체가 로드될 때 Adapter는 이러한 항목의 변경사항을 자동으로 감지합니다. 결과적으로 Adapter는 RecyclerView 개체 내에서 효율적인 항목 애니메이션을 트리거합니다.

 

다른 Adapter Type을 사용하여 Diffing

자체 Adapter 제공하는 Library를 사용할 때와 같이 PagedListAdapter에서 상속받지 않기로 선택했다면 AsyncPagedListDiffer 개체로 직접 작업함으로써 페이징 라이브러리 어댑터의 Diffing 기능을 사용할 수 있습니다.

 

UI에서 Placeholder 제공하기

앱이 데이터 가져오기를 완료하기 전에 UI에 List를 표시하려면 Placeholder List 항목을 사용자에게 표시할 수 있습니다.

PagedList는 데이터가 로드될 때까지 List 항목 데이터를 null로 표시함으로써 이러한 사례를 처리합니다.

 

Placeholder 사용 시 장점

Placeholder 사용 주의 사항

 

'Android jetpack' 카테고리의 다른 글

MVVM + Koin 최소 샘플 앱 개발 - part 2  (0) 2020.12.05
MVVM + Koin 최소 샘플 앱 개발 - part 1  (0) 2020.12.04
Paging Library - Gather Paged Data  (0) 2020.11.24
Paging Library - Overview  (0) 2020.11.24
WorkManager 알아보기  (0) 2020.11.23
Comments