Loading a PublisherAdView exactly once in RecyclerView

1,402 views
Skip to first unread message

Lisa Wray

unread,
Oct 25, 2016, 10:54:30 AM10/25/16
to Google Mobile Ads SDK Developers
We'd like to use a PublisherAdView as an item in a RecyclerView.  However, we'd like to load only one ad for the whole screen -- no matter how many times the ad is scrolled on and off the screen.

To accomplish this, we set the ad viewholders NOT recyclable in the adapter:

@Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int layoutResId) {
RecyclerView.ViewHolder viewHolder = super.onCreateViewHolder(parent, layoutResId);

// Don't recycle ads
if (layoutResId == R.layout.item_ad) {
viewHolder.setIsRecyclable(false);
}
return viewHolder;
}

The first time onBindViewHolder() is called, we call PublisherAdView.loadAd().  The ad loads successfully and is shown on screen.  

However, as soon as the ad view is scrolled off screen (i.e. detached from the window), scrolling it back on screen just shows a blank space.  

Can you point me to a correct implementation?  We do not want to call loadAd() multiple times -- we just want to be able to re-attach and re-display the first ad we loaded.

Thanks for any help!

Veer Arjun Busani(Mobile Ads SDK Team)

unread,
Oct 25, 2016, 11:45:00 AM10/25/16
to Google Mobile Ads SDK Developers
Hi Lisa,

I would suggest an alternative here. Instead of using setIsRecyclable(), you can try this - 

So let's say you have ViewHolder for just an AdView. Have an empty one and do not add the PublisherAdView here like this - 
public static class AdViewHolder extends RecyclerView.ViewHolder {
    public AdViewHolder(View view) {
        super(view);
    }
}
Next, in your list of RecyclerView Item's class, have a reference to the PublisherAdView to store it for reusing it. The idea is to externalize the caching process to show the AdView again when need. For example, your Item class can have be something like this -
   public class Item {
        protected String text;
        protected int viewType;
        protected Integer id;
        private static Integer ID = 1;

// Add this flag and AdView reference
        public Boolean newRequest;
        public PublisherAdView mAdView;
//
        public Item() {
            this.id = ID++;
        }

    }
Finally, in your onBindViewHolder(), for your AdView view type, have something like this - 
 case 1:{
                AdViewHolder viewHolder = (AdViewHolder) holder;

                LinearLayout linearLayout = (LinearLayout)viewHolder.itemView.findViewById(R.id.adViewContainer);
                LinearLayout.LayoutParams llp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,LinearLayout.LayoutParams.WRAP_CONTENT);
                PublisherAdView mAdView = new PublisherAdView(mContext);
                linearLayout.removeAllViews();

                if (item.newRequest) {
                    mAdView.setAdUnitId(mContext.getResources().getString(R.string.banner_ad_unit_id));
                    mAdView.setAdSizes(AdSize.BANNER);
                    PublisherAdRequest adRequest = new PublisherAdRequest.Builder().build();
                    mAdView.loadAd(adRequest);
                    item.newRequest = false;
                    item.mAdView = mAdView;
                } else {
                    mAdView = item.mAdView;
                }

                linearLayout.setLayoutParams(llp);
                ViewGroup parent = (ViewGroup)mAdView.getParent();
                if (parent != null) {
                    parent.removeView(mAdView);
                }
                linearLayout.addView(mAdView);
                break;
            }
It is a manual way to do this but it would ensure that you make only one AdRequest only. Let us know if you need anything else.

Thanks,
Arjun Busani
Mobile Ads SDK Team

Lisa Wray

unread,
Oct 25, 2016, 11:55:50 AM10/25/16
to Google Mobile Ads SDK Developers
Thank you so much for the super quick reply.  

I actually figured out another, even simpler way to do this.  You're right, setting ViewHolder.setIsRecycleable(false) is not the right way to do this.  

In the adapter, you can put:

@Override
public boolean onFailedToRecycleView(RecyclerView.ViewHolder holder) {
if (holder.getItemViewType() == R.layout.item_ad) {
// Don't recycle the ad view, keep it around
return true;
} else {
return super.onFailedToRecycleView(holder);
}
}

If you have an ad in your layout xml, that's all you need.  

Thanks for the help!
Reply all
Reply to author
Forward
0 new messages