Recylerview中的Admob Native Ads会在加载前显示空白区域

时间:2017-07-12 02:23:10

标签: android android-recyclerview admob google-admob

我已在我的应用中实施了Admob原生广告。它已被放置为在我的recyler视图中每4个项目显示一次。

问题是:在显示广告之前,空白空间将显示大约3到5秒,直到加载广告。我需要帮助才能删除此空白空间,并仅在完全加载原生广告时在广告系列之间加载广告。我在下面附上了2个屏幕截图:显示广告之前和之后。

Before displaying Ads After displaying Ads

适配器代码如下所示。

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);
        }
    }
}

布局文件 - 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"/>

4 个答案:

答案 0 :(得分:7)

如果您没有动态添加

,您可以设置视图的可见性,直到它加载为止
 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();

        }
    });

同样在onadfailedtoload中作为要求,我希望它可以帮助你。

答案 1 :(得分:2)

您可以让native_ad.xml只包含空的LinearLayout,并在广告加载后动态添加NativeExpressAdView

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"/>

动态创建NativeExpressAdView的对象,并仅在广告加载后将其添加到布局中。

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);
    }
}   

答案 2 :(得分:1)

我建议您提前加载广告并保留其中的队列,这样您就可以将完整加载的广告投放到RecyclerView而不是等待。

请查看我们的Native Express RecyclerView example,了解一种方法。

答案 3 :(得分:0)

考虑使用构造函数在recyclerview中加载您的商品,然后在您的父容器中加载广告,例如您的活动或片段。下载广告后,只需拨打电话即可通过创建来更新您的适配器适配器中的方法,如updateRecyclerView(NativeAd ad_loaded){ // Now here add this ad in your list and call notifyDataSetChanged() here }