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.
- Cómo obtener el elemento del adaptador RecyclerView en Android
- Cómo resaltar correctamente el elemento seleccionado en RecyclerView?
- LinearLayoutManager setOrientation después de rotación del teléfono no funciona
- Desactivar desplazamiento para posición en RecyclerView utilizando ItemTouchHelper.SimpleCallback
- Recyclerview - Superposición de artículos de abajo hacia arriba
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"/>
- Deslizar para descartar para RecyclerView
- Compruebe si RecyclerView es desplazable
- CheckBox en RecyclerView mantiene la comprobación de diferentes elementos
- Actualización de un ProgressBar en un RecyclerView
- Agregue una vista dinámicamente al elemento del RecyclerView
- Cómo implementar coverflow con recyclerview
- ¿Por qué no overScrollBy () y onOverScrolled () funcionan con RecyclerView
- Algo raro sucede mientras se desplaza RecyclerView demasiado rápido
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 }
- Poner cualquier vista sobre un VideoView en Android
- ¿Cómo empujar recylerView arriba cuando aparece el teclado?