✍️ cleverchuk
2024-06-15
sealed class UiState {
abstract var identifier: String
}
data class Task(val id: String, val name: String): UiState{
override var identifier: String
get() = id
set(_) {}
} data class DoerAd(val nativeAds: NativeAd?) : UiState(){
override var identifier: String
get() = nativeAds.toString()
set(_) {}
}
inner class AdsViewHolder(itemView: View) : BaseVH<UiState>(itemView) {
val binding = ItemAdsBinding.bind(itemView)
private val adLoader = AdLoader.Builder(itemView.context, adId)
.forNativeAd {
if (isDestroyed) {
it.destroy()
return@forNativeAd
}
binding.adsTemplate.setNativeAd(it)
ads.add(it)
}.build()
override fun bind(item: UiState) {
super.bind(item)
adLoader.loadAd(AdRequest.Builder().build())
}
}
class AdsAdapter<T : UiState, DelegateVH : BaseVH<T>>(
private val delegate: RecyclerView.Adapter<DelegateVH>,
val adId: String,
) : ListAdapter<UiState, BaseVH<T>>(UiStateDiff), LifecycleEventObserver {
private var isDestroyed = false
private val ads: MutableList<NativeAd> = mutableListOf()
private val adViewType = 1
private val adViewInterval = 3
inner class AdsViewHolder(itemView: View) : BaseVH<DoerAd>(itemView) {
val binding = ItemAdsBinding.bind(itemView)
private val adLoader = AdLoader.Builder(itemView.context, adId)
.forNativeAd {
if (isDestroyed) {
it.destroy()
return@forNativeAd
} binding.adsTemplate.setNativeAd(it)
ads.add(it)
}.build()
override fun bind(item: DoerAd) {
super.bind(item)
adLoader.loadAd(AdRequest.Builder().build())
}
}
companion object UiStateDiff : DiffUtil.ItemCallback<UiState>() {
override fun areItemsTheSame(oldItem: UiState, newItem: UiState) = oldItem.identifier == newItem.identifier
override fun areContentsTheSame(oldItem: UiState, newItem: UiState) = oldItem == newItem
}
override fun getItemViewType(position: Int): Int {
return if (isAdPosition(position)) adViewType else 0
}
private fun isAdPosition(position: Int): Boolean {
return (position + 1) % adViewInterval == 0
}
override fun submitList(list: MutableList<UiState>?) {
val states = mutableListOf<UiState>()
list?.forEachIndexed { position, state ->
if (isAdPosition(position)) {
states.add(position, DoerAd(null))
}
states.add(state)
}
super.submitList(states)
}
@Suppress("UNCHECKED_CAST")
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseVH<T> {
return if (viewType == adViewType) {
AdsViewHolder(
LayoutInflater.from(parent.context).inflate(
R.layout.item_ads, parent,
false
) ) as DelegateVH
} else {
delegate.onCreateViewHolder(parent, viewType)
}
}
@Suppress("UNCHECKED_CAST")
override fun onBindViewHolder(holder: BaseVH<T>, position: Int) {
if (getItemViewType(position) == 1) {
(holder as AdsAdapter<*, *>.AdsViewHolder).bind(currentList[position])
} else {
holder.bind(currentList[position] as T)
}
}
override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
if (event == Lifecycle.Event.ON_DESTROY) {
ads.forEach { it.destroy() }
ads.clear()
}
}
}
…
adapter = OldAdapter()
adsAdapter = AdsAdapter(adapter, adId)
recyclerView.adapter = adsAdapter
…
CleverCorp LLC © 2024
Mail us:
7901 4th St N STE 300
St. Petersburg
Florida, 33702