Pagination_Recyclerview_Android_Kotlin
Pagination_Recyclerview_Android_Kotlin copied to clipboard
Pagination Recyclerview Android Kotlin We use the Pagination Library of Android Jetpack in this app to fetch data from the database to recyclerView by retrofit API, This code is following the principl...
Pagination Recyclerview Android Kotlin
Pagination Recyclerview Android Java We use the Pagination Library of Android Jetpack in this app to fetch data from the database to recyclerView by retrofit API, This code is following the principles of MVVM design pattern and LiveData.
Screenshot Picture
/>
Installation
// add dependence of pagination to gradel script
def paging_version = "2.1.2"
implementation "androidx.paging:paging-runtime:$paging_version" // pagination
// add another dependencies [Optional]
implementation 'com.github.bumptech.glide:glide:4.11.0' // For Image
annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'
def retrofit2_version = "2.8.1" //Retrofit2
implementation "com.squareup.retrofit2:retrofit:$retrofit2_version"
implementation "com.squareup.retrofit2:converter-gson:$retrofit2_version"
def lifecycle_version = "2.2.0" //lifecycle
implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"
implementation "android.arch.lifecycle:extensions:$lifecycle_version"
annotationProcessor "android.arch.lifecycle:compiler:$lifecycle_version"
Create Abstract Class PaginationScrollListener
abstract class PaginationScrollListener (layoutManager: LinearLayoutManager) : RecyclerView.OnScrollListener() {
val layoutManager: LinearLayoutManager = layoutManager
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)
val visibleItemCount: Int = layoutManager.childCount
val totalItemCount: Int = layoutManager.itemCount
val firstVisibleItemPosition: Int = layoutManager.findFirstVisibleItemPosition()
if (!isLoading() && !isLastPage()) {
if ((visibleItemCount + firstVisibleItemPosition) >= totalItemCount && firstVisibleItemPosition >= 0) {
loadMoreItems()
}
}
}
protected abstract fun loadMoreItems()
abstract fun getTotalPageCount(): Int
abstract fun isLastPage(): Boolean
abstract fun isLoading(): Boolean
}
Usage
private val pageStart: Int = 1
private var isLoading: Boolean = false
private var isLastPage: Boolean = false
private var totalPages: Int = 1
private var currentPage: Int = pageStart
binding.recyclerMyOrders.addOnScrollListener(object : PaginationScrollListener(binding.recyclerMyOrders.layoutManager as LinearLayoutManager) {
override fun loadMoreItems() {
isLoading = true
currentPage += 1
Handler(Looper.myLooper()!!).postDelayed({
loadNextPage()
}, 1000)
}
override fun getTotalPageCount(): Int {
return totalPages
}
override fun isLastPage(): Boolean {
return isLastPage
}
override fun isLoading(): Boolean {
return isLoading
}
})
Create Adapter Class AdapterTopMoviesPagination
class AdapterTopMoviesPagination(private var mActivity: HomeActivity) : RecyclerView.Adapter<RecyclerView.ViewHolder>() ,
PaginationAdapterCallback{
private val item: Int = 0
private val loading: Int = 1
private var isLoadingAdded: Boolean = false
private var retryPageLoad: Boolean = false
private var errorMsg: String? = ""
private var moviesModels: MutableList<ResultsItem> = ArrayList()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return if(viewType == item){
val binding: ItemMovieBinding = DataBindingUtil.inflate(LayoutInflater.from(parent.context), R.layout.item_movie, parent, false)
TopMoviesVH(binding)
}else{
val binding: ItemLoadingBinding = DataBindingUtil.inflate(LayoutInflater.from(parent.context), R.layout.item_loading, parent, false)
LoadingVH(binding)
}
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
val model = moviesModels[position]
if(getItemViewType(position) == item){
val myOrderVH: TopMoviesVH = holder as TopMoviesVH
myOrderVH.itemRowBinding.movieProgress.visibility = View.VISIBLE
myOrderVH.bind(model)
}else{
val loadingVH: LoadingVH = holder as LoadingVH
if (retryPageLoad) {
loadingVH.itemRowBinding.loadmoreErrorlayout.visibility = View.VISIBLE
loadingVH.itemRowBinding.loadmoreProgress.visibility = View.GONE
if(errorMsg != null) loadingVH.itemRowBinding.loadmoreErrortxt.text = errorMsg
else loadingVH.itemRowBinding.loadmoreErrortxt.text = mActivity.getString(R.string.error_msg_unknown)
} else {
loadingVH.itemRowBinding.loadmoreErrorlayout.visibility = View.GONE
loadingVH.itemRowBinding.loadmoreProgress.visibility = View.VISIBLE
}
loadingVH.itemRowBinding.loadmoreRetry.setOnClickListener{
showRetry(false, "")
retryPageLoad()
}
loadingVH.itemRowBinding.loadmoreErrorlayout.setOnClickListener{
showRetry(false, "")
retryPageLoad()
}
}
}
override fun getItemCount(): Int {
return if (moviesModels.size > 0) moviesModels.size else 0
}
override fun getItemViewType(position: Int): Int {
return if(position == 0){
item
}else {
if (position == moviesModels.size - 1 && isLoadingAdded) {
loading
} else {
item
}
}
}
override fun retryPageLoad() {
mActivity.loadNextPage()
}
class TopMoviesVH(binding: ItemMovieBinding) : RecyclerView.ViewHolder(binding.root) {
var itemRowBinding: ItemMovieBinding = binding
fun bind(obj: Any?) {
itemRowBinding.setVariable(BR.model, obj)
itemRowBinding.executePendingBindings()
}
}
class LoadingVH(binding: ItemLoadingBinding) : RecyclerView.ViewHolder(binding.root) {
var itemRowBinding: ItemLoadingBinding = binding
}
fun showRetry(show: Boolean, errorMsg: String) {
retryPageLoad = show
notifyItemChanged(moviesModels.size - 1)
this.errorMsg = errorMsg
}
fun addAll(movies: MutableList<ResultsItem>) {
for(movie in movies){
add(movie)
}
}
fun add(moive: ResultsItem) {
moviesModels.add(moive)
notifyItemInserted(moviesModels.size - 1)
}
fun addLoadingFooter() {
isLoadingAdded = true
add(ResultsItem())
}
fun removeLoadingFooter() {
isLoadingAdded = false
val position: Int =moviesModels.size -1
val movie: ResultsItem = moviesModels[position]
if(movie != null){
moviesModels.removeAt(position)
notifyItemRemoved(position)
}
}
Please note that Pagination Library is a well-supported and Free License, so you can use the app and edit.