Admob Native Ads dentro de un Recylerview muestra espacio en blanco antes de cargar

He implementado anuncios nativos de Admob en mi aplicación. Se ha colocado para exhibir una vez para cada 4 artículos en mi opinión del recyler. El problema es que antes de que se muestren los anuncios, se mostrará un espacio en blanco de alrededor de 3 a 5 segundos hasta que se cargue el anuncio. Necesito ayuda para eliminar este espacio en blanco y cargar el anuncio entre los elementos de vista de reciclador sólo cuando el anuncio nativo se carga completamente. He adjuntado una captura de pantalla antes y después de mostrar anuncios.

Introduzca aquí la descripción de la imagen Introduzca aquí la descripción de la imagen

El código del adaptador se ve más abajo.

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

}

El archivo de diseño xml de native_ad se ve como a continuación.

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

Usted puede tener su native_ad.xml sólo contienen un LinearLayout vacío y agregar el NativeExpressAdView dinámicamente al diseño una vez que se carga el anuncio.

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

Cree un objeto de NativeExpressAdView de forma dinámica y agréguelo a la presentación sólo una vez que se cargue el anuncio.

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

Puede establecer la visibilidad de la vista hasta que se cargue si no está agregando dinámicamente

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

Similarmente en onadfailedtoload como requisito espero que pueda ayudarle.

Te recomendamos cargar tus anuncios de antemano y mantener una cola de ellos en la reserva, por lo que sólo puede pop un anuncio totalmente cargado en el RecyclerView en lugar de esperar.

Echa un vistazo a nuestro ejemplo de Native Express RecyclerView para obtener una forma de hacerlo.

Considere la posibilidad de cargar sus artículos en recyclerview con Constructor y luego cargar su anuncio en su contenedor padre es decir, su actividad o fragmento. Una vez que haya descargado el anuncio, simplemente haga una llamada para actualizar su adaptador creando un método en su adaptador como updateRecyclerView(NativeAd ad_loaded){ // Now here add this ad in your list and call notifyDataSetChanged() here }

  • Android TV RecyclerView interacción con el foco
  • Decoración de artículos de RecyclerView
  • RecyclerView se bloquea cuando "las vistas desechadas o conectadas no se pueden reciclar"
  • RecyclerView vuelve a calcular WRAP_CONTENT
  • Android: Elemento RecyclerView cuando se establece en bloques que se pueden hacer clic en eventos onTouch
  • ¿Por qué RecyclerView no tiene onItemClickListener ()?
  • Pausar un video en un recicladorVer cuando hay un cierto porcentaje en la pantalla
  • RecyclerView muestra los datos eliminados en la lista
  • Android reciclerview no muestra elementos
  • RecyclerView y java.lang.IndexOutOfBoundsException: Inconsistencia detectada. Posicionador de visor no válido PositionViewHolder en dispositivos Samsung
  • ¿Cómo mostrar diferentes diseños en recyclerView?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.