chayanforyou

Native Ads with RecyclerView

May 7th, 2026
28
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Kotlin 9.74 KB | None | 0 0
  1. package com.oss.abraakadabraaapp.datasource
  2.  
  3. import android.util.Log
  4. import android.view.LayoutInflater
  5. import android.view.View
  6. import android.view.ViewGroup
  7. import android.widget.Button
  8. import android.widget.ImageView
  9. import android.widget.RatingBar
  10. import android.widget.TextView
  11. import androidx.constraintlayout.widget.ConstraintLayout
  12. import androidx.core.content.ContextCompat
  13. import androidx.paging.PagingDataAdapter
  14. import androidx.recyclerview.widget.DiffUtil
  15. import androidx.recyclerview.widget.RecyclerView
  16. import com.bumptech.glide.Glide
  17. import com.google.android.gms.ads.AdListener
  18. import com.google.android.gms.ads.AdLoader
  19. import com.google.android.gms.ads.AdRequest
  20. import com.google.android.gms.ads.LoadAdError
  21. import com.google.android.gms.ads.formats.UnifiedNativeAd
  22. import com.google.android.gms.ads.nativead.NativeAd
  23. import com.google.android.gms.ads.nativead.NativeAdOptions
  24. import com.google.android.gms.ads.nativead.NativeAdView
  25. import com.oss.abraakadabraaapp.R
  26. import com.oss.abraakadabraaapp.datasource.products.Product
  27. import java.util.Locale
  28.  
  29. class ProductAdapter(val onClick: OnProductClicked) :
  30.     PagingDataAdapter<Product, RecyclerView.ViewHolder>(ProductDifferntiator) {
  31.  
  32.     private val ADS_AFTER: Int = 17 //frequency of ads in list
  33.     private val ITEM_VIEW: Int = R.layout.item_product //regular item view layout
  34.     private val AD_VIEW: Int = R.layout.list_ad  //ad view layout
  35.  
  36.     class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
  37.         var tv = itemView.rootView.findViewById<TextView>(R.id.tv_product_name)
  38.         var tv_product_distance = itemView.rootView.findViewById<TextView>(R.id.tv_product_distance)
  39.         var tv_product_location = itemView.rootView.findViewById<TextView>(R.id.tv_product_location)
  40.         var iv = itemView.rootView.findViewById<ImageView>(R.id.iv_product)
  41.         var my_product: ConstraintLayout =
  42.             itemView.rootView.findViewById<ConstraintLayout>(R.id.iv_given)
  43.  
  44.         fun bind(item: Product?) {
  45.             tv.text =
  46.                 item?.name?.replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() }
  47.             Glide.with(itemView.context).load(item?.display_image)
  48.                 .placeholder(R.drawable.image_placeholder).into(iv)
  49.             tv_product_distance.setText("${(item?.distance?.div(1000))} KM")
  50.             tv_product_location.setText("${item?.condition}")
  51.  
  52.             if (item!!.isSelfProduct) {
  53.                 my_product.visibility = View.VISIBLE
  54.                 iv.background =
  55.                     ContextCompat.getDrawable(itemView.context, R.color.transparent_blur)
  56.             } else {
  57.                 my_product.visibility = View.GONE
  58.             }
  59.  
  60.         }
  61.     }
  62.  
  63.     /* override fun onBindViewHolder(holder: ViewHolder, position: Int) {
  64.          holder.bind(getItem(position))
  65.          holder.itemView.setOnClickListener {
  66.              Log.d("NewReceiverFragment", "bind: ${getItem(position)?.name}")
  67.              onClick.onProductClicked(getItem(position),position)
  68.          }
  69.      }*/
  70.  
  71.     override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
  72.  
  73.         if(getItemViewType(position) == AD_VIEW){
  74.             val qholder = holder as NativeAdViewHolder
  75.             qholder.loadAds()
  76.             return
  77.         }
  78.         val item = getItem(position)
  79.         val qholder = holder as ViewHolder
  80.         qholder.bind(item) // whatever you likes
  81.         qholder.itemView.setOnClickListener {
  82.             Log.d("NewReceiverFragment", "bind: ${getItem(position)?.name}")
  83.             onClick.onProductClicked(getItem(position), position)
  84.         }
  85.  
  86.     }
  87.  
  88.     override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
  89.         return /*ViewHolder(LayoutInflater
  90.             .from(parent.context)
  91.             .inflate(R.layout.item_product, parent, false))*/ when (viewType) {
  92.             AD_VIEW -> NativeAdViewHolder(
  93.                 LayoutInflater.from(parent.context).inflate(AD_VIEW, parent, false)
  94.             )
  95.  
  96.             ITEM_VIEW -> ViewHolder(
  97.                 LayoutInflater
  98.                     .from(parent.context)
  99.                     .inflate(R.layout.item_product, parent, false)
  100.             )
  101.  
  102.             else -> ViewHolder(
  103.                 LayoutInflater
  104.                     .from(parent.context)
  105.                     .inflate(R.layout.item_product, parent, false)
  106.             )
  107.         }
  108.     }
  109.  
  110.     companion object ProductDifferntiator : DiffUtil.ItemCallback<Product>() {
  111.  
  112.         override fun areItemsTheSame(oldItem: Product, newItem: Product): Boolean {
  113.             return oldItem.id == newItem.id
  114.         }
  115.  
  116.         override fun areContentsTheSame(oldItem: Product, newItem: Product): Boolean {
  117.             return oldItem == newItem
  118.         }
  119.     }
  120.  
  121.     interface OnProductClicked {
  122.         fun onProductClicked(product: Product?, position: Int)
  123.     }
  124.  
  125.     override fun getItemViewType(position: Int): Int {
  126.         return if (isAdPosition(position)) AD_VIEW else ITEM_VIEW
  127.     }
  128.  
  129.     private fun isAdPosition(position: Int): Boolean {
  130.         return position > 0 && (position + 1) % ADS_AFTER == 0
  131.     }
  132.    /* override fun getItemCount(): Int {
  133.         //disclaimer: copied from the stackoverflow link below but its working fine for me
  134.         val s = super.getItemCount()
  135.         var t: Int = s + s / ADS_AFTER
  136.         if (s > 0) t++ // +1 when list is not empty
  137.         // Utils.showLog("☺☺☺ total is $t, real are $s")
  138.         return t
  139.     }*/
  140.  
  141.     class NativeAdViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
  142.  
  143.         init {
  144.  
  145.             loadAds()
  146.  
  147.         }
  148.  
  149.         fun loadAds() {
  150.             val adLoader = AdLoader.Builder(itemView.context, "ca-app-pub-6795450348346297/5355595380")
  151.                 .forNativeAd {
  152.                     val adView = itemView as NativeAdView
  153.                     populateUnifiedNativeAdView(it, adView)
  154.                 }
  155.                 .withNativeAdOptions(
  156.                     NativeAdOptions.Builder()
  157.                         // Methods in the NativeAdOptions.Builder class can be
  158.                         // used here to specify individual options settings.
  159.                         .build()
  160.                 )
  161.                 .build()
  162.             adLoader.loadAd(AdRequest.Builder().build())
  163.         }
  164.  
  165.         private fun populateUnifiedNativeAdView(nativeAd: NativeAd, adView: NativeAdView) {
  166.             // Set the media view.
  167.             adView.mediaView = adView.findViewById(R.id.ad_media)
  168.  
  169.             // Set other ad assets.
  170.             adView.headlineView = adView.findViewById(R.id.ad_headline)
  171.             adView.bodyView = adView.findViewById(R.id.ad_body)
  172.             adView.callToActionView = adView.findViewById(R.id.ad_call_to_action)
  173.             adView.iconView = adView.findViewById(R.id.ad_app_icon)
  174.             adView.priceView = adView.findViewById(R.id.ad_price)
  175.             adView.starRatingView = adView.findViewById(R.id.ad_stars)
  176.             adView.storeView = adView.findViewById(R.id.ad_store)
  177.             adView.advertiserView = adView.findViewById(R.id.ad_advertiser)
  178.  
  179.             // The headline and media content are guaranteed to be in every UnifiedNativeAd.
  180.             (adView.headlineView as TextView).text = nativeAd.headline
  181.             adView.mediaView?.setMediaContent(nativeAd.mediaContent)
  182.  
  183.             // These assets aren't guaranteed to be in every UnifiedNativeAd, so it's important to
  184.             // check before trying to display them.
  185.             if (nativeAd.body == null) {
  186.                 adView.bodyView?.visibility = View.INVISIBLE
  187.             } else {
  188.                 adView.bodyView?.visibility = View.VISIBLE
  189.                 (adView.bodyView as TextView).text = nativeAd.body
  190.             }
  191.  
  192.             if (nativeAd.callToAction == null) {
  193.                 adView.callToActionView?.visibility = View.INVISIBLE
  194.             } else {
  195.                 adView.callToActionView?.visibility = View.VISIBLE
  196.                 (adView.callToActionView as Button).text = nativeAd.callToAction
  197.             }
  198.  
  199.             if (nativeAd.icon == null) {
  200.                 adView.iconView?.visibility = View.GONE
  201.             } else {
  202.                 (adView.iconView as ImageView).setImageDrawable(
  203.                     nativeAd.icon!!.drawable
  204.                 )
  205.                 adView.iconView?.visibility = View.VISIBLE
  206.             }
  207.  
  208.             if (nativeAd.price == null) {
  209.                 adView.priceView?.visibility = View.INVISIBLE
  210.             } else {
  211.                 adView.priceView?.visibility = View.VISIBLE
  212.                 (adView.priceView as TextView).text = nativeAd.price
  213.             }
  214.  
  215.             if (nativeAd.store == null) {
  216.                 adView.storeView?.visibility = View.INVISIBLE
  217.             } else {
  218.                 adView.storeView?.visibility = View.VISIBLE
  219.                 (adView.storeView as TextView).text = nativeAd.store
  220.             }
  221.  
  222.             if (nativeAd.starRating == null) {
  223.                 adView.starRatingView?.visibility = View.INVISIBLE
  224.             } else {
  225.                 (adView.starRatingView as RatingBar).rating = nativeAd.starRating!!.toFloat()
  226.                 adView.starRatingView?.visibility = View.VISIBLE
  227.             }
  228.  
  229.             if (nativeAd.advertiser == null) {
  230.                 adView.advertiserView?.visibility = View.INVISIBLE
  231.             } else {
  232.                 (adView.advertiserView as TextView).text = nativeAd.advertiser
  233.                 adView.advertiserView?.visibility = View.VISIBLE
  234.             }
  235.  
  236.             // This method tells the Google Mobile Ads SDK that you have finished populating your
  237.             // native ad view with this native ad.
  238.             adView.setNativeAd(nativeAd)
  239.         }
  240.  
  241.     }
  242. }
Add Comment
Please, Sign In to add comment