Search code examples
androidandroid-recyclerviewadmobandroid-adapternative-ads

Admob Native ads in RecyclerView android


I am facing this issue with my Recycler view while placing admob ads

Problem: It is actually replaced the item from the list and place the ads

enter image description here

After apply this solution recommended by one of the stack-overflow member the problem occur

How to place Admob Native Advanced Ads in recycler view android?

This is code i am using:

@Override
public int getItemViewType(int position) {
    if (position>1 && (position+1) % 4 == 0) {

        return AD_TYPE;
    } else {

        return CONTENT_TYPE;
    }

}

@Override
public int getItemCount() {
    return articleList.size();
}

Here is full code

public class ArticleAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{
private Context mContext;
private List<ArticleJson> articleList;
String titleoflist;
private static final int AD_TYPE = 2;
private static final int CONTENT_TYPE = 1;

public class MyViewHolder extends RecyclerView.ViewHolder {
    TextView txtTitle;
    LinearLayout linearLayout;
    private ArticleJson m_articleJson;

    public MyViewHolder(View view) {
        super(view);
        txtTitle = view.findViewById(R.id.texViewArticleTitle);
      
    }

    public void bindView(final ArticleJson articleJson){
        m_articleJson = articleJson;

    }
}

class adViewHolder extends RecyclerView.ViewHolder {
    TemplateView Adtemplate;
    UnifiedNativeAdView unifiedNativeAdView;

    public adViewHolder(@NonNull View itemView) {
        super(itemView);
        Adtemplate = itemView.findViewById(R.id.mednative_placeholder1);
        unifiedNativeAdView = itemView.findViewById(R.id.native_ad_view);
    }
}

public ArticleAdapter(Context mContext, List<ArticleJson> articleList,String titleoflist) {
    this.mContext = mContext;
    this.articleList = articleList;
    this.titleoflist = titleoflist;
}


@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    if (viewType == AD_TYPE) {
        adViewHolder madViewHolder = new adViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_ads, null, false));
        return madViewHolder;
    } else{
        MyViewHolder mYourViewHolder = new MyViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_article, null, false));
        return mYourViewHolder;
    }
}

@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
    if (getItemViewType(position) == CONTENT_TYPE) {
        final ArticleJson articleJson = articleList.get(position);
        ((MyViewHolder)holder).bindView(articleJson);
        ((MyViewHolder)holder).linearLayout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
             
            }
        });

}else if (getItemViewType(position) == AD_TYPE){

        MobileAds.initialize(mContext, new OnInitializationCompleteListener() {
            @Override
            public void onInitializationComplete(InitializationStatus initializationStatus) {}
        });

        AdLoader adLoader2 = new AdLoader.Builder(mContext, "ca-app-pub-8376062614303044/3237856178")
                .forUnifiedNativeAd(new UnifiedNativeAd.OnUnifiedNativeAdLoadedListener() {
                    @Override
                    public void onUnifiedNativeAdLoaded(UnifiedNativeAd unifiedNativeAd) {
                        UnifiedNativeAdView unifiedNativeAdView = ((adViewHolder) holder).unifiedNativeAdView;
                        unifiedNativeAdView.setVisibility(View.VISIBLE);
                        NativeTemplateStyle styles = new
                                NativeTemplateStyle.Builder().build();

                        TemplateView template = ((adViewHolder) holder).Adtemplate;
                        template.setStyles(styles);
                        template.setNativeAd(unifiedNativeAd);


                    }
                })
                .build();

        adLoader2.loadAd(new AdRequest.Builder().build());



    }
}

@Override
public int getItemCount() {
    return articleList.size();
}

@Override
public int getItemViewType(int position) {
    if (position>1 && (position+1) % 4 == 0) {

        return AD_TYPE;
    } else {

        return CONTENT_TYPE;
    }

}

}

public class ArticleJson {
private String mid;
private String mTitle;
boolean isAd = false;

public ArticleJson() {

}
public ArticleJson(String mid, String mTitle) {
    this.mTitle = mTitle;
    this.mid = mid;
}

public String getMid() {
    return mid;
}

public String getmTitle() {
    return mTitle;
}}

Solution

  • The problem occurred because you are using only the original data list in your adapter without having the ads objects into the list. So according to your example above you will have only 10 items (original data) instead of 13 (with the ads objects).

    To achieve the result you want without affecting the original data you can do something like below:

    1.Change your ArticleAdapter constructor to be like below. Here i have created a new List of ArticleJson (articlesWithAdsList) which holds both ads and items and i am placing each Ad in every 3rd row using the adPos (Ad frequency number) variable where you can change this according to your needs. To distinguish the Ad from item i have added a boolean flag isAd in the ArticleJson object and finally your articleList is pointing to the new created articlesWithAdsList.

    public ArticleAdapter(Context mContext, List<ArticleJson> articleList, String titleoflist) {
            this.mContext = mContext;
            //prepare a new List<ArticleJson> having both ads and data
            List<ArticleJson> articlesWithAdsList = new ArrayList<>();
            if(articleList!=null && articleList.size()>0)
            {
                int adPos = 0;
                //iterate through the actual data list and prepare the new articlesWithAdsList
                for (int i = 0; i < articleList.size(); i++)
                {
                    //initialize and add the ad in every 3rd row
                    if(adPos == 3) {
                        ArticleJson advertise = new ArticleJson();
                        advertise.isAd = true;
                        articlesWithAdsList.add(advertise);
                        adPos = 0;
                    }
                    //and add the actual Item ArticleJson object
                    ArticleJson articleJson = articleList.get(i);
                    articleJson.isAd = false;
                    articlesWithAdsList.add(articleJson);
                    adPos++;
                }
            }
            //articleList now have both ads and data items
            this.articleList = articlesWithAdsList;
            this.titleoflist = titleoflist;
        }
    

    2.Change getItemViewType(int position) to use the isAd flag to distinguish the AD_TYPE from Item CONTENT_TYPE like below:

    @Override
    public int getItemViewType(int position) {
        ArticleJson articleJson = articleList.get(position);
        if (articleJson.isAd) {
            return AD_TYPE;
        } else {
            return CONTENT_TYPE;
        }
    }
    

    3.And finally add the isAd flag into your ArticleJson object:

    public class ArticleJson {
        boolean isAd = false;
        public ArticleJson() {
       
        }
    }