개발일지

Android in A..Z - Paging (PagingAdapter) 본문

Android (안드로이드)/Paging

Android in A..Z - Paging (PagingAdapter)

강태종 2021. 5. 25. 12:00

PagingAdapter

RecyclerView와 결합하여 사용할 수 있고, LoadState로 Loading, Error 등 상황을 표시할 수 있습니다.


코드

BasePagingAdapter

abstract class BasePagingAdapter<E: Any>(itemCallback: DiffUtil.ItemCallback<E>) : PagingDataAdapter<E, BaseHolder<out ViewDataBinding, E>>(itemCallback) {
    override fun onBindViewHolder(holder: BaseHolder<out ViewDataBinding, E>, position: Int) {
        getItem(position)?.let { holder.bind(it) }
    }

    override fun onBindViewHolder(holder: BaseHolder<out ViewDataBinding, E>, position: Int, payloads: MutableList<Any>) {
        super.onBindViewHolder(holder, position, payloads)
        getItem(position)?.let { holder.bind(it, payloads) }
    }
}

 

ViewerPagingAdapter

class ViewerPagingAdapter : BasePagingAdapter<String>(itemCallback) {
    companion object {
        private val itemCallback = object : DiffUtil.ItemCallback<String>() {
            override fun areItemsTheSame(oldItem: String, newItem: String): Boolean {
                return oldItem.hashCode() == newItem.hashCode()
            }

            override fun areContentsTheSame(oldItem: String, newItem: String): Boolean {
                return oldItem == newItem
            }
        }
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseHolder<out ViewDataBinding, String> {
        return ViewerHolder(
            HolderViewerBinding.inflate(
                LayoutInflater.from(parent.context), parent, false
            )
        )
    }

    override fun getItemViewType(position: Int): Int {
        return R.layout.holder_viewer
    }

    inner class ViewerHolder(binding: HolderViewerBinding) : BaseHolder<HolderViewerBinding, String>(binding) {
        override fun bind(element: String) {
            super.bind(element)
            binding.imageUrl = element
        }
    }
}

 

ViewerFragment

        lifecycleScope.launch {
            viewerPagingAdapter.loadStateFlow.collect {
                Log.d("PASS", it.toString())
                when {
                    it.refresh is LoadState.Loading -> {
                        /*
                        Pager is Loading
                         */
                    }

                    it.prepend is LoadState.Error ||
                            it.append is LoadState.Error ||
                            it.refresh is LoadState.Error -> {
                        /*
                        Handle Error
                         */
                    }
                }
            }
        }
        lifecycleScope.launch {
            viewModel.getPagingData(webToon, episode).collect {
                viewerPagingAdapter.submitData(it)
            }
        }

LoadState를 통해 Loading, Error, NotLoading 3가지 상태를 알 수 있다.

  • CombinedLoadStates.append : PagingData의 Load가 끝난 상태
  • CombinedLoadStates.mediator : RemoteMediator가 호출된 상태 (RemoteMediator가 없을 경우 null)
  • CombinedLoadStates.prepend : PagingData의 Load가 시작된 상태
  • CombinedLoadStates.recycle : PagingData를 새로 고치는 중

submitData로 PagingSource에서 얻은 Data를 Update할 수 있다.


Git (예제 코드)

https://github.com/KangTaeJong98/Example/tree/main/Android/Paging

 

KangTaeJong98/Example

My Example Code. Contribute to KangTaeJong98/Example development by creating an account on GitHub.

github.com

 

Comments