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