kotlinandroid-recyclerviewpaginationnestedrecyclerviewscroll-paging

How to implement nested paging in android kotlin?


I have a recyclerview , for i using pagin 3 with coroutine live data . but child recyclerview also have paginate data so how can i perform this nested pagination in android kotlin.


Solution

  • So , I done this with pagination for child recyclerview inside recyclerview . Firstly of all call api for fetch dates and perform api for every date at same time when date are fetching.

    so structure like this...

    lateinit var adapter: WeeklyAdapter
    lateinit var dayAdapter: DayDetailsPagingAdapter
    
    
        private fun observeData() {
            viewModel.weeklyAcquiringDetails(AcquiringVM.WEEKLY, "").observe(this){
                wsWithLoader(it){
                    binding.rvAcquiringWeeklyDetails.adapter = WeeklyAdapter(it.data!!.data, object : WeeklyAdapter.OnPerformApi{
                        override fun performApi(date: String, rvMonthly: RecyclerView) {
                            dayAdapter = DayDetailsPagingAdapter(object  : DayDetailsPagingAdapter.OnClick{
                                override fun onClick(result: DayAcquiring.Data) {}
                            })
                            rvMonthly.adapter = dayAdapter
                            lifecycleScope.launchWhenCreated {
                                viewModel.getDayAcquiringDetails(date).collectLatest { data ->
                                    dayAdapter.submitData(data)
                                }
                            }
                        }
                    })
                }
            }
        }
    

    Weekly Adapter

    class WeeklyAdapter (
            val list: List<WeeklyAcquiring.Data>,
            val action: OnPerformApi
        ) : RecyclerView.Adapter<WeeklyAdapter.ViewHolder>() {
        
            @NonNull
            override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
                return ViewHolder(DataBindingUtil.inflate(LayoutInflater.from(parent.context), R.layout.list_monthly, parent, false))
            }
        
            override fun onBindViewHolder(holder: ViewHolder, position: Int) {
                val result = list[position]
                holder.binding.apply {
                    tvDate.text = changeDateFormat(result.doctorScheduleDate,"yyyy-MM-dd","E, dd MMM yyyy")
                    action.performApi( result.doctorScheduleDate , rvMonthly)
                }
            }
        
            override fun getItemCount(): Int {
                return list.size
            }
        
            inner class ViewHolder(binding: ListMonthlyBinding) : BaseViewHolder<ListMonthlyBinding>(binding) {}
        
            interface OnPerformApi{
                fun performApi(date : String, rvMonthly: RecyclerView)
            }
            }
    

    list_monthly_layout

    <?xml version="1.0" encoding="utf-8"?>
    <layout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools">
    
        <data>
    
        </data>
    
        <androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
    
            <TextView
                android:id="@+id/tvDate"
                style="@style/TVBold"
                android:layout_marginTop="@dimen/_5sdp"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textSize="@dimen/_12sdp"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent"
                tools:text="May 2022" />
    
            <androidx.recyclerview.widget.RecyclerView
                android:id="@+id/rvMonthly"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="@dimen/_10sdp"
                app:layout_constraintEnd_toEndOf="parent"
                app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
                app:layout_constraintStart_toStartOf="parent"
                tools:listitem="@layout/list_acquiring_details"
                app:layout_constraintTop_toBottomOf="@+id/tvDate" />
    
        </androidx.constraintlayout.widget.ConstraintLayout>
    
    </layout>
    

    DayDetailsPagingAdapter

    class DayDetailsPagingAdapter (private val onClick: OnClick) : PagingDataAdapter<DayAcquiring.Data, DayDetailsPagingAdapter.ViewHolder>(DiffCallback()) {
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        return ViewHolder(ListAcquiringDetailsBinding.inflate(LayoutInflater.from(parent.context), parent, false))
    }
    
    @SuppressLint("SetTextI18n")
    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val result = getItem(position)!!
        holder.binding.apply {
            data = result
            tvName.text = result.userName
            tvAmount.text = "€ ${result.amount}"
        }
    }
    
    class ViewHolder(val binding: ListAcquiringDetailsBinding) : RecyclerView.ViewHolder(binding.root) {}
    
    private class DiffCallback : DiffUtil.ItemCallback<DayAcquiring.Data>() {
        override fun areItemsTheSame(
            oldItem: DayAcquiring.Data,
            newItem: DayAcquiring.Data
        ): Boolean = oldItem == newItem
    
        override fun areContentsTheSame(
            oldItem: DayAcquiring.Data,
            newItem: DayAcquiring.Data
        ): Boolean = oldItem == newItem
    }
    
    interface OnClick {
        fun onClick(result: DayAcquiring.Data )
    }
    }
    

    **in viewmodel **

    fun getDayAcquiringDetails( date: String ) = apiHelper.getDayAcquiringDetails( date ).cachedIn(viewModelScope)
    fun weeklyAcquiringDetails( filter: String ,  date: String) = apiHelper.weeklyAcquiringDetails( filter , date)
    

    hope you like this .