【问题标题】:Admob Native Ads inside a Recyclerview displays blank space before loadingRecyclerview 中的 Admob 原生广告在加载前显示空白
【发布时间】:2017-07-12 02:23:09
【问题描述】:

我已在我的应用程序中实施 Admob 原生广告。在我的回收站视图中,它已被放置为每 4 个项目显示一次。

问题是:在展示广告之前,会出现大约 3 到 5 秒的空白区域,直到广告加载完毕。我需要帮助来删除此空白区域并仅在完全加载原生广告时才在回收站视图项之间加载广告。我在下面附上了 2 个屏幕截图:展示广告之前和之后。

适配器代码如下所示。

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

【问题讨论】:

  • 我面临同样的问题,你能告诉我你是如何在片段中添加原生快速广告视图
  • @SRBhagwat 能否将原生广告在回收站视图中的完整实施发送给我。我很难实现它。

标签: android android-recyclerview admob


【解决方案1】:

如果您不动态添加,您可以设置视图的可见性,直到它加载为止

 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 中执行要求,希望对您有所帮助。

【讨论】:

    【解决方案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);
        }
    }   
    

    【讨论】:

      【解决方案3】:

      我建议提前加载您的广告并保留它们的队列,这样您就可以将一个完全加载的广告弹出到 RecyclerView 而不是等待。

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

      【讨论】:

      • 是的,我已经参考了代码,他们使用 List,而我在整个项目中使用 List。那么有没有办法通过不将 List 更改为 List 来解决这个问题?
      • a google demo 关于在 recyclerview 中使用原生广告
      【解决方案4】:

      考虑使用 Constructor 在 recyclerview 中加载您的项目,然后将您的广告加载到您的父容器中,即 您的 Activity 或 Fragment。 下载广告后,只需通过创建调用来更新您的适配器适配器中的方法,例如 updateRecyclerView(NativeAd ad_loaded){ // Now here add this ad in your list and call notifyDataSetChanged() here }

      【讨论】:

        猜你喜欢
        • 2021-10-02
        • 1970-01-01
        • 2021-06-09
        • 1970-01-01
        • 1970-01-01
        • 2021-10-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多