Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Admob Native Ads inside a Recyclerview displays blank space before loading

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.

Before displaying Ads 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"/>

like image 991
SRBhagwat Avatar asked Jul 12 '17 02:07

SRBhagwat


2 Answers

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.

like image 58
jigar savaliya Avatar answered Nov 19 '22 04:11

jigar savaliya


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);
    }
}   
like image 3
Abhishek Jain Avatar answered Nov 19 '22 03:11

Abhishek Jain