I am using paging library to fetch data from server, I was thinking of showing Ad after every 10 items. So as the user scrolls down and new items are fetched and added to PagedList. I want the new Ad to be loaded and added in RecyclerView
as well just like Instagram shows ads in feeds. So if the user scrolls to 200 items, 20 ads will be shown gradually!!. I have read a couple of tutorials but I haven't figured an easy way to do it.
Here is my adapter.
class RequestsPagedAdapter(
private val retryCallback: () -> Unit, private val from: From)
: PagedListAdapter<RequestsQuery.Request, RecyclerView.ViewHolder>(POST_COMPARATOR) {
private var networkState: NetworkState? = null
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
when (getItemViewType(position)) {
R.layout.z_request_item -> (holder as RequestViewHolder).bind(getItem(position)!!, from)
R.layout.network_state_item -> (holder as NetworkStateItemViewHolder).bindTo(networkState)
R.layout.ad_admob_banner -> (holder as AdMobViewHolder)
}
}
override fun onBindViewHolder(
holder: RecyclerView.ViewHolder,
position: Int,
payloads: MutableList<Any>) {
if (payloads.isNotEmpty()) {
val item = getItem(position)
(holder as RequestViewHolder).updateProduct(item!!)
} else {
onBindViewHolder(holder, position)
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return when (viewType) {
R.layout.z_request_item -> RequestViewHolder.create(parent)
R.layout.network_state_item -> NetworkStateItemViewHolder.create(parent, retryCallback)
R.layout.ad_admob_banner -> AdMobViewHolder.create(parent)
else -> throw IllegalArgumentException("unknown view type $viewType")
}
}
private fun hasExtraRow() = networkState != null && networkState != NetworkState.LOADED
override fun getItemViewType(position: Int): Int {
return when {
hasExtraRow() && position == itemCount - 1 -> R.layout.network_state_item
position % ITEMS_PER_AD == 0 + 2 -> R.layout.ad_admob_banner
else -> R.layout.z_request_item
}
}
override fun getItemCount(): Int {
return super.getItemCount() + if (hasExtraRow()) 1 else 0
}
fun setNetworkState(newNetworkState: NetworkState?) {
val previousState = this.networkState
val hadExtraRow = hasExtraRow()
this.networkState = newNetworkState
val hasExtraRow = hasExtraRow()
if (hadExtraRow != hasExtraRow) {
if (hadExtraRow) {
notifyItemRemoved(super.getItemCount())
} else {
notifyItemInserted(super.getItemCount())
}
} else if (hasExtraRow && previousState != newNetworkState) {
notifyItemChanged(itemCount - 1)
}
}
companion object {
val POST_COMPARATOR = object : DiffUtil.ItemCallback<RequestsQuery.Request>() {
override fun areContentsTheSame(oldItem: RequestsQuery.Request, newItem: RequestsQuery.Request): Boolean =
oldItem == newItem
override fun areItemsTheSame(oldItem: RequestsQuery.Request, newItem: RequestsQuery.Request): Boolean =
oldItem.id() == newItem.id()
}
}
}
This is how data is submitted to PagedList
from Fragment
.
private fun getRequests() {
subcategoryRequestsListViewModel.requests.observe(viewLifecycleOwner, Observer {
adapter.submitList(it)
})
subcategoryRequestsListViewModel.networkState.observe(viewLifecycleOwner, Observer {
adapter.setNetworkState(it)
})
}
And ViewHolder
class AdMobViewHolder(view: View) : RecyclerView.ViewHolder(view) {
companion object {
fun create(parent: ViewGroup): AdMobViewHolder {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.ad_admob_banner, parent, false)
return AdMobViewHolder(view)
}
}
}