I have implemented Admob native ads in my application. It has been placed to display once for every 4 items in my recycler view.
The problem is: before ads are being displayed, a blank space will be shown up for around 3 to 5 seconds till the ad is loaded. I need help to remove this blank space and load the ad in between recycler view items only when the native ad is loaded completely. I have attached 2 screenshots below: before and after displaying ads.
Adapter code looks like below.
public class MovieAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private Context mContext;
private List<Movie> mList;
private LayoutInflater mLayoutInflater;
private static final int DEFAULT_VIEW_TYPE = 1;
private static final int NATIVE_AD_VIEW_TYPE = 2;
public MovieAdapter(Context c, List<Movie> l) {
this(c, l, true, true);
}
public MovieAdapter(Context c, List<Movie> l, boolean wa, boolean wcl) {
mContext = c;
mList = l;
mLayoutInflater = (LayoutInflater) c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public int getItemViewType(int position) {
if (position!=0 && position%4 == 0) {
return NATIVE_AD_VIEW_TYPE;
}
return DEFAULT_VIEW_TYPE;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
View v;
switch (viewType) {
default:
v = mLayoutInflater.inflate(R.layout.item_movie_card, viewGroup, false);
return new MyViewHolder(v);
case NATIVE_AD_VIEW_TYPE:
v = mLayoutInflater.inflate(R.layout.list_item_native_ad, viewGroup, false);
return new NativeAdViewHolder(v);
}
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
if (!(holder instanceof MyViewHolder)) {
return;
}
MyViewHolder myViewHolder = (MyViewHolder) holder;
myViewHolder.tvName.setText(mList.get(position).getName());
myViewHolder.tvGenre.setText(mList.get(position).getGenre());
ControllerListener listener = new BaseControllerListener() {
@Override
public void onFinalImageSet(String id, Object imageInfo, Animatable animatable) {
super.onFinalImageSet(id, imageInfo, animatable);
}
@Override
public void onFailure(String id, Throwable throwable) {
super.onFailure(id, throwable);
}
@Override
public void onIntermediateImageFailed(String id, Throwable throwable) {
super.onIntermediateImageFailed(id, throwable);
}
@Override
public void onIntermediateImageSet(String id, Object imageInfo) {
super.onIntermediateImageSet(id, imageInfo);
}
@Override
public void onRelease(String id) {
super.onRelease(id);
}
@Override
public void onSubmit(String id, Object callerContext) {
super.onSubmit(id, callerContext);
}
};
int w = 0;
if (myViewHolder.ivMovie.getLayoutParams().width == FrameLayout.LayoutParams.MATCH_PARENT
|| myViewHolder.ivMovie.getLayoutParams().width == FrameLayout.LayoutParams.WRAP_CONTENT) {
Display display = ((Activity) mContext).getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
try {
w = size.x;
} catch (Exception e) {
w = display.getWidth();
}
}
Uri uri = Uri.parse(DataUrl.getUrlCustom(mList.get(position).getUrlPhoto(), w));
DraweeController dc = Fresco.newDraweeControllerBuilder()
.setUri(uri)
.setTapToRetryEnabled(true)
.setControllerListener(listener)
.setOldController(myViewHolder.ivMovie.getController())
.build();
myViewHolder.ivMovie.setController(dc);
}
@Override
public int getItemCount() {
return mList.size();
}
public void addListItem(Movie c, int position) {
mList.add(c);
notifyItemInserted(position);
}
public void removeListItem(int position) {
mList.remove(position);
notifyItemRemoved(position);
}
public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public SimpleDraweeView ivMovie;
public TextView tvName;
public TextView tvGenre;
public ImageButton imageButton;
public MyViewHolder(View itemView) {
super(itemView);
ivMovie = (SimpleDraweeView) itemView.findViewById(R.id.iv_car);
tvName = (TextView) itemView.findViewById(R.id.tv_model);
tvGenre = (TextView) itemView.findViewById(R.id.tv_brand);
imageButton = (ImageButton) itemView.findViewById(R.id.like_button);
}
@Override
public void onClick(View v) {
}
}
public class NativeAdViewHolder extends RecyclerView.ViewHolder {
private final NativeExpressAdView mNativeAd;
public NativeAdViewHolder(final View itemView) {
super(itemView);
mNativeAd = (NativeExpressAdView) itemView.findViewById(R.id.nativeAd);
mNativeAd.setAdListener(new AdListener() {
@Override
public void onAdLoaded() {
super.onAdLoaded();
}
@Override
public void onAdClosed() {
super.onAdClosed();
}
@Override
public void onAdFailedToLoad(int errorCode) {
super.onAdFailedToLoad(errorCode);
}
@Override
public void onAdLeftApplication() {
super.onAdLeftApplication();
}
@Override
public void onAdOpened() {
super.onAdOpened();
}
});
AdRequest adRequest = new AdRequest.Builder()
.addTestDevice(AdRequest.DEVICE_ID_EMULATOR)
.build();
mNativeAd.loadAd(adRequest);
}
}
}
Layout file - native_ad.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:ads="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="132dp">
<com.google.android.gms.ads.NativeExpressAdView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/nativeAd"
ads:adSize="FULL_WIDTHx132"
ads:adUnitId="@string/native_ad_unit"/>
you may set visibility of view untill it loaded if you are not adding dynamically
public NativeAdViewHolder(final View itemView) {
super(itemView);
itemView.setVisibility(View.GONE);
mNativeAd = (NativeExpressAdView) itemView.findViewById(R.id.nativeAd);
mNativeAd.setAdListener(new AdListener() {
@Override
public void onAdLoaded() {
super.onAdLoaded();
itemView.setVisibility(View.VISIBLE);
}
@Override
public void onAdClosed() {
super.onAdClosed();
}
@Override
public void onAdFailedToLoad(int errorCode) {
super.onAdFailedToLoad(errorCode);
}
@Override
public void onAdLeftApplication() {
super.onAdLeftApplication();
}
@Override
public void onAdOpened() {
super.onAdOpened();
}
});
similarly do in onadfailedtoload as requirement i hope it may help you.
You can have your native_ad.xml
just contain an empty LinearLayout
and add the NativeExpressAdView
dynamically to the layout once the ad is loaded.
native_ad.xml :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
Create an object of NativeExpressAdView dynamically and add it to the layout only once the ad is loaded.
public class NativeAdViewHolder extends RecyclerView.ViewHolder {
private final LinearLayouot containerView;
public NativeAdViewHolder(final View itemView) {
super(itemView);
containerView = itemView;
NativeExpressAdView mNativeAd = new NativeExpressAdView(itemView.getContext());
mNativeAd.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT));
mNativeAd.setId(R.id.nativeAd);
mNativeAd.setAdSize(new AdSize(AdSize.FULL_WIDTH, 132));
mNativeAd.setAdUnitId("yourAdUnitId");
mNativeAd.setAdListener(new AdListener() {
@Override
public void onAdLoaded() {
super.onAdLoaded();
containerView.addView(mNativeAd);
}
...All other overriden methods
});
AdRequest adRequest = new AdRequest.Builder()
.addTestDevice(AdRequest.DEVICE_ID_EMULATOR)
.build();
mNativeAd.loadAd(adRequest);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With