Search code examples
androidandroid-intentandroid-recyclerviewadmobadapter

Android get correct item position after admob native ads are added to recycler view


I am showing admob native ads in recycleview and i was sucessful in doing so and the ads are loading just fine . now the problem that i am facing is that i need to show item clicked in another activity along its position but when click any item after the ads are loaded in recycleview i get the wrong position. Can anyone give me an idea how to do this or is there a better way to do what i am trying to achieve here. Here is my code

Adapter

private final List<Object> modelBase;
Context context;
List<Quote> quoteList;

public AdapterList(Context context, List<Object> modelBase) {
    this.context = context;
    this.modelBase = modelBase;
}

public void setQuoteListForNextActivity(List<Quote> quoteList) {
    this.quoteList = quoteList;
}
  @Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
    int viewType = getItemViewType(position);
    switch (viewType) {

        case 1:
            UnifiedNativeAd nativeAd = (UnifiedNativeAd) modelBase.get(position);
            populateNativeAdView(nativeAd, ((UnifiedNativeAdViewHolder) holder).getAdView());
            break;

        case 0:
            //Not really needed code here as we have the default.

        default:
            MyListHolder menuItemHolder = (MyListHolder) holder;
            Quote menuItem = (Quote) modelBase.get(position);
            menuItemHolder.itemTitle.setText(menuItem.getQuote());
            menuItemHolder.itemDescription.setText(String.valueOf(menuItem.getId()));

            menuItemHolder.itemView.setOnClickListener(v -> {

                Intent intent = new Intent(context, NextACtivity.class);
                Bundle bundle = new Bundle();
                bundle.putParcelableArrayList("mylist", (ArrayList<? extends Parcelable>) quoteList);
                bundle.putInt("position",position);
                intent.putExtras(bundle);
               context.startActivity(intent);
            });
    }
}

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

@Override
public int getItemViewType(int position) {
    Object recyclerViewItem = modelBase.get(position);
    if (recyclerViewItem instanceof UnifiedNativeAd) {
        return 1;
    }
    return 0;
}

public class MyListHolder extends RecyclerView.ViewHolder {

        private TextView itemTitle, itemDescription;

        MyListHolder(View view) {
            super(view);
            itemTitle = view.findViewById(R.id.itemTitle);
            itemDescription = view.findViewById(R.id.itemDescription);
        }
    }

    //ViewHolder for Native Ad Data
    class UnifiedNativeAdViewHolder extends RecyclerView.ViewHolder {

        private UnifiedNativeAdView adView;

        public UnifiedNativeAdView getAdView() {
            return adView;
        }

        UnifiedNativeAdViewHolder(View view) {
            super(view);
            adView = view.findViewById(R.id.ad_view);
            adView.setMediaView((MediaView) adView.findViewById(R.id.ad_media));
            adView.setHeadlineView(adView.findViewById(R.id.ad_headline));
            adView.setBodyView(adView.findViewById(R.id.ad_body));
            adView.setCallToActionView(adView.findViewById(R.id.ad_bt_visit));
            adView.setIconView(adView.findViewById(R.id.ad_icon));
            adView.setPriceView(adView.findViewById(R.id.ad_price));
            adView.setStarRatingView(adView.findViewById(R.id.ad_stars));
            adView.setStoreView(adView.findViewById(R.id.ad_store));
            adView.setAdvertiserView(adView.findViewById(R.id.ad_advertiser));
        }
    }

And Here is my MainActicity

private String ADMOB_NATIVE_AD_UNIIT = "ca-app-pub-3940256099942544/2247696110";

AdLoader adLoader;

// The total number of native ads to load.
private static final int NUMBER_OF_ADS = 5;
//FIRST AD POSITION (Index number, means List position + 1)
public static final int FIRST_AD_START_POSITION = 7;
AdapterList adapterList;
List<Object> mDataList = new ArrayList<>();
List<UnifiedNativeAd> mNativeAds = new ArrayList<>();


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    MobileAds.initialize(this, initializationStatus -> {

    });
    AppDatabase database = AppDatabase.getDatabase(this);
    QuoteDao dao = database.quoteDao();


    RecyclerView recyclerView = findViewById(R.id.quote_recyclerview);
    recyclerView.setHasFixedSize(true);
    recyclerView.setLayoutManager(new LinearLayoutManager(this));
    recyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));

    mDataList.addAll( dao.getAllQuotes());
    adapterList = new AdapterList(this,mDataList);
    recyclerView.setAdapter(adapterList);

    adapterList.setQuoteListForNextActivity(dao.getAllQuotes());
    loadNativeAds();

}
private void insertAdsInMenuItems() {
    if (mNativeAds.size() <= 0) {
        return;
    }
    int offset = (mDataList.size() / mNativeAds.size()) + 1;
    int index = FIRST_AD_START_POSITION;
    for (UnifiedNativeAd ad : mNativeAds) {
        mDataList.add(index, ad);
        index = index + offset;
    }
    adapterList.notifyDataSetChanged();
}

private void loadNativeAds() {
    AdLoader.Builder builder = new AdLoader.Builder(this, ADMOB_NATIVE_AD_UNIIT);
    adLoader = builder.forUnifiedNativeAd(
            unifiedNativeAd -> {
                mNativeAds.add(unifiedNativeAd);
                if (!adLoader.isLoading()) {
                    insertAdsInMenuItems();
                }
            }).withAdListener(
            new AdListener() {
                @Override
                public void onAdFailedToLoad(LoadAdError loadAdError) {
                    if (!adLoader.isLoading()) {
                        insertAdsInMenuItems();
                    }
                }
            }).build();
    adLoader.loadAds(new AdRequest.Builder().build(), NUMBER_OF_ADS);
}

Solution

  • You can try the following 2 solutions:

    Solution 1: Count items prior to position that are data[ItemViewType is 0].

        int originalListPosition = 0;
        for (int i = 0; i < position; i++) {
            if (getItemViewType(i) == 0) originalListPosition++;
        }
    

    Solution 2: Pass index and offset from Activity to Adapter and do calculation.

        int originalListPosition;
        if (position < index) originalListPosition = position;
        else {
            originalListPosition = position - ((position - index) / offset + 1);
        }