在加载之前,Recylerview内的Admob原生广告显示空白区域

我在我的应用程序中实施了Admob原生广告。 它被放置在我的recyler视图中每4个项目显示一次。 问题在于广告显示之前,直到广告加载完成时,空白区域会显示大约3到5秒。 只有当原生广告完全加载时,我需要帮助才能删除此空白区域,并在回收站视图项目之间加载广告。 在展示广告前后,我附上了一个截图。

在这里输入图像说明 在这里输入图像说明

适配器代码如下所示。

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

您可以让native_ad.xml只包含一个空的LinearLayout并在加载广告后dynamic地将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"/> 

只有在加载广告后,才能dynamic创buildNativeExpressAdView对象并将其添加到布局。

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

如果不是dynamic添加,您可以设置视图的可见性直到它加载

  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作为要求,我希望它可以帮助你。

我build议提前加载您的广告,并保留其中的一个队列,以便您可以将满载的广告popup到RecyclerView中,而不是等待。

查看我们的Native Express RecyclerView示例,了解如何执行此操作。

考虑使用Constructor在recyclerview中加载您的项目,然后将您的广告加载到您的父容器(即您的活动或片段)中。 一旦你有广告下载,然后只需打电话更新您的适配器通过在您的适配器中创build一个方法,如updateRecyclerView(NativeAd ad_loaded){ // Now here add this ad in your list and call notifyDataSetChanged() here }