我已在我的应用中实施了Admob原生广告。它已被放置为在我的recyler视图中每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"/>
答案 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
}