androidkotlinandroid-paging

android: kotlin: Data not loading in adapter while implementing paging 3


I was implementing paging 3 in my app.

I tried to follow google codelabs and overview on paging 3 from documentation

However it fails to display the data in the adapter, I put logs in the adapter and no logs from adapter show up on logcat.

I tried to debug the codelabs code and data flow was exactly as mine, since I can't( or don't know yet) how to intervene paging which is received in flow in fragment, I am unable to tell if my fragment receives the data. Also I have never used adapter.submitdata() and new to coroutines, I am not sure if it could be the scope which is the problem.

Any help is appreciated. Thanks in advance.

Have a nice day.

fragment

        transactionsAdapterPaging = TransactionsPagedListAdapter()
        homeFragmentDataBinding.transactionsRV.apply {
            layoutManager = LinearLayoutManager(requireContext())
            setHasFixedSize(true)
            adapter = transactionsAdapterPaging
        }

        homeFragmentDataBinding.transactionsRV.adapter = transactionsAdapterPaging

        lifecycleScope.launch {
            mainViewModel.getDataFromRemote().collectLatest {
                Log.e(TAG, "initializeTransactionAdapter:  ++++++++====== " + it.toString())
                transactionsAdapterPaging.submitData(it)

            }
        }

viewmodel

    private var currentSearchResult: Flow<PagingData<TransactionDetail>>? = null

    fun getDataFromRemote(): Flow<PagingData<TransactionDetail>> {
        val lastResult = currentSearchResult
        val newResult: Flow<PagingData<TransactionDetail>> = mainRepository.getDataFromRemote()
            .cachedIn(viewModelScope)
        currentSearchResult = newResult
        return newResult
    }

repository

    fun getDataFromRemote(): Flow<PagingData<TransactionDetail>> {
        return Pager(
            config = PagingConfig(pageSize = 1, enablePlaceholders = false),
            pagingSourceFactory = { TransactionsDataSource() }
        ).flow
    }

data source

class TransactionsDataSource() : PagingSource<Int, TransactionDetail>() {
    private val TAG = "UserDataSource"
    override suspend fun load(params: LoadParams<Int>): LoadResult<Int, TransactionDetail> {

        val position = params.key ?: 1
        return try {
            lateinit var transactionDetail: List<TransactionDetail>

            var response: Response<Any?>? = NewAPIServiceClient.getAllTransactionsPaging(
                Application.getInstance(),
                Prefs.getString(Constants.CARD_UUID_IN_USE, ""),
                position,
                null
            )

            Log.e(TAG, "load: " + response)

            if (response != null &&  response.isSuccessful) {
                if (response?.body() != null) {

                    val gson = Gson()
                    try {
                        val jsonObject1 = JSONObject(gson.toJson(response?.body()))
                        val transactionsGson = jsonObject1.getJSONArray(Constants.PN_DATA_NEW)
                        transactionDetail = gson.fromJson(
                            transactionsGson.toString(),
                            object : TypeToken<List<TransactionDetail>?>() {}.type
                        )
                    } catch (e:Exception){

                    }
                }
            }

            val repos = transactionDetail

            Log.e(TAG, "load: ===== " + repos.toString()  )

            return LoadResult.Page(
                data = repos,
                prevKey = if (position == 1) null else position - 1,
                nextKey = if (repos.isEmpty()) null else position + 1
            )



        } catch (exception: IOException) {
            Log.e(TAG, "load: 11111111111111111 " + exception )
            LoadResult.Error(exception)
        } catch (exception: HttpException) {
            Log.e(TAG, "load: 11111111111111111 " + exception )
            LoadResult.Error(exception)
        }


    }

}

adapter

class TransactionsPagedListAdapter() :
    PagingDataAdapter<TransactionDetail, RepoViewHolder>(
        DIFF_CALLBACK
    ) {
    private val TAG = "AdapterPaging"
    private var serviceListFiltered: List<TransactionDetail>? = null

    override fun onCreateViewHolder(
        parent: ViewGroup,
        viewType: Int
    ): RepoViewHolder {
        Log.e(TAG, "onCreateViewHolder: ")
        val itemBinding: RvListItemTransactionsHomeBinding =
            RvListItemTransactionsHomeBinding.inflate(
                LayoutInflater.from(parent.context),
                parent,
                false
            )
        return RepoViewHolder(itemBinding)
    }

    override fun onBindViewHolder(
        holder: RepoViewHolder,
        position: Int
    ) {
        Log.e(TAG, "onBindViewHolder: ")
        val repoItem = getItem(position)
        if (repoItem != null) {
            (holder).bind(repoItem, position)
        }
    }

    override fun getItemCount(): Int {
        return if (serviceListFiltered == null) {
            0
        } else serviceListFiltered!!.size
    }


    companion object {
        val DIFF_CALLBACK = object : DiffUtil.ItemCallback<TransactionDetail>() {
            override fun areItemsTheSame(oldItem: TransactionDetail, newItem: TransactionDetail) =
                oldItem.uuid == newItem.uuid


            override fun areContentsTheSame(
                oldItem: TransactionDetail,
                newItem: TransactionDetail
            ) =
                oldItem == newItem

        }
    }


}


class RepoViewHolder internal constructor(itemBinding: RvListItemTransactionsHomeBinding) :
    RecyclerView.ViewHolder(itemBinding.getRoot()), View.OnClickListener {
    private val mDataBinding: RvListItemTransactionsHomeBinding = itemBinding
    var rootView: View
    fun bind(invoice: TransactionDetail, position: Int) {
        rootView.transaction_text_title.text = invoice.merchant?.merchantName
        var amountWithSymbol =
            Utilities.getFormattedAmount(
                Application.getInstance()?.applicationContext,
                invoice.amount.toString()
            )
        rootView.transaction_amount.text = amountWithSymbol
        rootView.transactions_date.text = invoice.timestamp
    }

    override fun onClick(view: View) {
        if (adapterPosition > RecyclerView.NO_POSITION) {
        }
    }

    init {
        val itemView: View = itemBinding.getRoot()
        rootView = mDataBinding.constraintContainer
        itemView.setOnClickListener(this)
    }
}

Solution

  • `override fun getItemCount(): Int = serviceListFiltered?.size ?: 0`
    

    Don't override getItemCount in your recyclerview adapter.